Kezdőoldal » Számítástechnika » Programozás » String kezelés! Replace...

String kezelés! Replace függvény hibaüzenet? többi lent!

Figyelt kérdés

Sziasztok! Olyan problémán van, hogy kéne egy olyan programot írnom, ami bekér egy karakterláncot, egy behelyettesítendő karakterláncot, egy számot, hogy hányszor menjen végig a folyamat, egy min számot, és egy max számot. Az első lépést követően a behelyettesítő karakterlánc az előző ciklusiterációban létrejövő kimenet.A végleges kimenet ezek összefűzése A min szám jelenti azt, hogy a végleges kimenet hanyadik karakterétől, a max pedig azt, hogy a végleges kimenet hanyadik karakteréig kell kiíratni. Ha a végső karakterek száma kevesebb, mint amit az indexek definiálnak, akkor a megjelenített kimenet a -jellel kerüljön kiegészítésre. Pl. bemenetek: helyettesítendő: e átírandó:$agl$ hányszor: 2 min:1 max: 15 kimenet:eagleagleagle-- vagy: bemenetek: helyettesítendő: b átírandó:$o$ hányszor: 10 min:1 max: 3 kimenet:bob Az első kettő ajánlott tesztbemenettekkel jól működik az általam megírt kód. Azonban akadnak olyan bemenetek, ahol elszáll a Replace függvény hibaüzenettel: Evaluting expression 'helyettesintedo'. A problémás bemenet: bemenetek: helyettesítendő: oenik átírandó:$$ hányszor: 100 min:1 max: 50 kimenet:oenikoenikoenikoenikoenikoenikoenikoenikoenikoenik vagy van még egy problémás bemenet: bemenetek: helyettesítendő: x átírandó:$a$b$c$ hányszor: 999999999 min:33 max: 65 kimenet:xaxbxcxaxaxbxcxbxaxbxcxcxaxbxcxbx Ez esetben a Replace függvény System.OutOfMemory Exception Exeption WasThrown hibaüzenettel áll le. Van egy olyan bemenet is, hogy nem tartalmaz az átírandó karakterlánc $-jelet: bemenetek: helyettesítendő: 0 átírandó:1hányszor: 1000000000 min:10000 max: 10009 kimenet:---------- Ezért van minden elágazásban egy

if program.Contains($) felétel.

A fenti bemenet működik is a segítségével. Illetve van egy olyan eset, hogy a min-1 nagyobb,mint a kimenet hossza, ez esetben nincs mit kiírnia a programnak, itt a bemenetek és a kért kimenetek: bemenetek: helyettesítendő: nik átírandó:oe$ hányszor: 10min:150 max: 175 kimenet:----------------------- Ezt is sikerült az


else if(min - 1 > kimenet.Length&& program.Contains("$"))

{

for (int i = 0; i < kimenet.Length; i = i + 1)

{

kimenetvegleges = kimenetvegleges + "-";

kimenetvegleges2 = kimenetvegleges;

}

}


elágazással megoldanom.



Valamit sikerült alkotnom, a kód:

using System;

namespace _3.házi_feladat

{

class Program

{

static void Main(string[] args)

{

string helyettesitendo = Console.ReadLine();

string program = Console.ReadLine();

int hanyszor = int.Parse(Console.ReadLine());

int min = int.Parse(Console.ReadLine());

int max = int.Parse(Console.ReadLine());

string kimenet = "";

string kimenetvegleges = "";

string kimenetvegleges2 = "";

for (int i = 0; i < hanyszor; i = i + 1)

{

if (program.Contains("$"))

{

kimenet = program.Replace("$", helyettesitendo);

helyettesitendo = kimenet;

}



}//Console.WriteLine(kimenet);


if (min - 1 <= kimenet.Length&& program.Contains("$"))

{ kimenetvegleges = kimenet.Substring(min - 1, kimenet.Length - (min - 1)); }

else if(min - 1 > kimenet.Length&& program.Contains("$"))

{

for (int i = 0; i < kimenet.Length; i = i + 1)

{

kimenetvegleges = kimenetvegleges + "-";

kimenetvegleges2 = kimenetvegleges;

}

}

if (max <= kimenet.Length && kimenet.Length > min - 1&& program.Contains("$"))

{

int levag = kimenet.Length - max;

kimenetvegleges2 = kimenetvegleges.Substring(0, kimenetvegleges.Length - levag);

}

else if (max > kimenet.Length && kimenet.Length > min - 1&& program.Contains("$"))

{

int kevesebb = max - kimenet.Length;

for (int i = 0; i < kevesebb; i = i + 1)

{

kimenetvegleges = kimenetvegleges + "-";

}

kimenetvegleges2 = kimenetvegleges;

}

else if(!program.Contains("$"))

{

int hanyszorhanincs = (max - min) + 1;

for (int j = 0; j < hanyszorhanincs; j = j + 1)

{ kimenetvegleges = kimenetvegleges + "-"; }

kimenetvegleges2 = kimenetvegleges;

}

Console.WriteLine(kimenetvegleges2);

}

}

}

A kérdésem tehát, hogy a replace függvény fenti hibaüzeneteit mi okozhatja, és mit kell tennem a hiba elhárítása érdekében. A válaszaitok előre is köszi.


2021. nov. 4. 11:12
 1/10 anonim ***** válasza:
OutOfMemorey exceptiont kapsz. Elég egyértelmű mi a gond, de protip: ha egymilliárdszor meghívod a replace-t ciklusban, azt lehet nem fogja szeretni a gép...
2021. nov. 4. 11:47
Hasznos számodra ez a válasz?
 2/10 anonim ***** válasza:
Nem csoda, hogy elfogy a memóriád ha minden iterációban új stringet gyártasz és ez lefut egymilliárdszor. Használj StringBuildert.
2021. nov. 4. 11:59
Hasznos számodra ez a válasz?
 3/10 A kérdező kommentje:
A StrinBuilder ről még nem hallottam! Az mi pontosan? Leírnátok, hogy hogyan kell használni?
2021. nov. 4. 12:39
 4/10 anonim ***** válasza:

[link]


Itt írja az elején, hogy a stringek megváltoztathatatlanok (immutable), szóval ha hozzáírsz valamit egy stringhez, akkor valójában létrehoz egy másodikat.


A StringBuilder viszont dinamikusan méretezi magát a módosításkor. Itt elérheted, milyen metódusokat ismer: [link]


Objektum létrehozást new kulcsszóval, objektumok metódusainak meghívását, objektumokra mutató (referencia) változók működését ismerni kell ehhez.

2021. nov. 4. 13:05
Hasznos számodra ez a válasz?
 5/10 anonim ***** válasza:

Igazából nem feltétlen kell ide StringBuilder. Legalábbis azok a példabemenetek mennek nélküle is, amiket írtál.


Annyi volt a trükk, hogy ha a vizsgált intervallumon (min és max között) nem változik a kimenet egyik iterációról a másikra, akkor az már azután se fog, szóval le lehet állítani a ciklust. Ez alól persze kivétel a csak -----t tartalmazó, ezt külön kell vizsgálni.


Ha magad szeretnéd megoldani, akkor ne nézd meg:

[link]

2021. nov. 4. 14:54
Hasznos számodra ez a válasz?
 6/10 anonim ***** válasza:
Egy else ágat kihagytam: [link]
2021. nov. 4. 15:07
Hasznos számodra ez a válasz?
 7/10 A kérdező kommentje:
Köszönöm, de sajna ez egy beanandó, ahol a "break" tiltott metódus. Ezért Substring-gel próbálom megoldani, de nem teljesen sikerült sajna még: A Substring lényegét értettem, azonban úgy vettem észre, hogy a Replace függvény nem tud kezelni csak stringet, ezért ott stringgé konvertáltam a szintén substring helyettesítendőt. A helyettesítendő azért StringBuilder, mert a for cikluson belül egyenlővé kell tenni a korábbi kimenettel. Azonban mivel stringé konvertálom a helyettesítendőt, ezért ha egymilliárszor kell a for ciklust végighajtani, akkor is tele lesz a memória. Másik: sajna, azokra a bemenetekre, amikre az eddig magamtól írt kód jó kimenetet adott, sajna amit próbáltam a string Builderrel írni, arra sem ad jó kimenetet, mivel a atringbuilder append parancsánál benne marad a string builder stringben, amit már előzőleg hozzáadtunk, ami miatt pl az bemenetek: helyettesítendő: e átírandó:$agl$ hányszor: 2 min:1 max: 15 kimenet:eagleagleagle-- bemenetnél a vágatlan kimenet az eagleagleagle helyett eagleeagleagleagle lesz,a végső pedig az eagleagleagle-- helyett eagleeagleaglea , tehát benne marad, amit az előző iterációkban hozzáfűzött az Append metódus. Ha próbálom a for cikluson belul a kimenet StringBuildert a clear paranccsal lenullázni, akkor meg egyáltalán semmilyen kimenete nem lesz a programmnak. Légyszi segítsetek még. Előre is köszönöm s segítséget.
2021. nov. 4. 16:17
 8/10 A kérdező kommentje:

A módosított kódom:

using System;

using System.Text;


namespace _3.házi_feladat

{

class Program

{

static void Main(string[] args)

{


StringBuilder helyettesitendo = new StringBuilder("");

helyettesitendo.Append (Console.ReadLine());

string program = Console.ReadLine();

int hanyszor = int.Parse(Console.ReadLine());

int min = int.Parse(Console.ReadLine());

int max = int.Parse(Console.ReadLine());


StringBuilder kimenet = new StringBuilder("");

string kimenet2 = "";

string kimenetvegleges = "";

string kimenetvegleges2 = "";


for (int i = 0; i < hanyszor; i = i + 1)


{

if (program.Contains("$"))

{



kimenet.Append ( program.Replace("$", Convert.ToString(helyettesitendo)));



helyettesitendo = kimenet;


Console.WriteLine(kimenet);

Console.WriteLine("");


}



kimenet2 = Convert.ToString(kimenet);

}//Console.WriteLine(kimenet);

//Console.WriteLine(kimenet2);


if (min - 1 <= kimenet2.Length&& program.Contains("$"))

{ kimenetvegleges = kimenet2.Substring(min - 1, kimenet2.Length - (min - 1)); }

else if(min - 1 > kimenet2.Length&& program.Contains("$"))

{

for (int i = 0; i < kimenet2.Length; i = i + 1)

{

kimenetvegleges = kimenetvegleges + "-";

kimenetvegleges2 = kimenetvegleges;

}

}



if (max <= kimenet2.Length && kimenet2.Length > min - 1&& program.Contains("$"))

{

int levag = kimenet2.Length - max;

kimenetvegleges2 = kimenetvegleges.Substring(0, kimenetvegleges.Length - levag);



}

else if (max > kimenet2.Length && kimenet2.Length > min - 1&& program.Contains("$"))

{

int kevesebb = max - kimenet2.Length;

for (int i = 0; i < kevesebb; i = i + 1)

{


kimenetvegleges = kimenetvegleges + "-";



}

kimenetvegleges2 = kimenetvegleges;


}

else if(!program.Contains("$"))

{

int hanyszorhanincs = (max - min) + 1;

for (int j = 0; j < hanyszorhanincs; j = j + 1)

{ kimenetvegleges = kimenetvegleges + "-"; }

kimenetvegleges2 = kimenetvegleges;

}

Console.WriteLine(kimenetvegleges2);

}

}

}

2021. nov. 4. 16:18
 9/10 anonim ***** válasza:

Egyrészt a StringBuilder-nek is van Replace metódusa, nem kell a string-ét hívogatni, másrészt ToString metódusa is van, nem kell a Convert-é.


Igen, az a baj, hogy a kimenetbe appendelsz, aztán a helyettesitendo változót is ráállítod arra az SB-re amire a kimenet is mutat, így már mindkettő arra mutat, és azt az SB-t, amire a helyettesitendo mutatott, elviszi a garbage collection, mert már nem mutat rá semmi. Így működik, de ennél lehet szebben:


kimenet.Clear();

kimenet.Append(program.Replace("$", Convert.ToString(helyettesitendo)));

helyettesitendo.Clear();

helyettesitendo.Append(kimenet.ToString());


Én úgy csináltam, hogy egy harmadik, temp nevű SB változót használtam, hogy megcseréljem a kettőt. A kimenetben helyben Replace-ltem, megcseréltem a helyettesitendo-vel, majd (ami a helyettesitendo volt) kitöröltem, és visszaraktam bele a program stringet. Így működik, de így is csak az egyszerű példákra:

[link]


Az a baj, hogy StringBuilderrel is felduzzad a memória, mert a StringBuilder megnő. Gondolj bele pl. az oenik és $$ esetében kb. 2^i-vel lesz arányos a StringBuilder mérete. Ez nem fog kibírni 100 iterációt, már lehet 2^30 körül megtelik a RAM. És némelyik példa (mondjuk $a$b$c$) még durvábban nő.


Ökörségnek tartom ezt, hogy tiltott a break, mert semmibe nem telik a break kikerülésével átírni a programot, hogy ugyanúgy működjön, csak a ciklus feltételébe kell beleírni a break feltételét, csak egy kicsit rondább lesz:

[link]


Ezzel ugyanúgy megy, mint a break-kel.

2021. nov. 4. 18:05
Hasznos számodra ez a válasz?
 10/10 A kérdező kommentje:
Nagyon szépen köszönöm a segítséget!
2021. nov. 4. 20:27

Kapcsolódó kérdések:




Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!