String kezelés! Replace függvény hibaüzenet? többi lent!
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.
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.
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:
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);
}
}
}
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:
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:
Ezzel ugyanúgy megy, mint a break-kel.
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
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!