Pascal: két szövegfájl tartalmából azt szeretném megkapni, amit csak egyik vagy csak másik fájl tartalmaz. Ami mindkettőben megvan azt nem. Miként kell ezt?
Szeretném megvalósítani azt, hogy beolvasom két tömbbe F és F2 sorait, egyenként szeretném végignézni, hogy ha F2 nem tartalmazza F bizonyos sorát (és fordítva ugyanígy), akkor az egy külön harmadik fájlba kerüljön.
Beolvasás után szeretném összehasonlítani a sorokat, minden sort minden sorral és ez az ami nem megy.
F2 első sorát F2 összes sorával, F2 második sorát F összes sorával...
Kizárólag azok kerülnének kiírásra, amelyeket csak az egyik fájl tartalmaz.
Mi a módja ennek?
A string típus praktikus és jó, ha biztosan tudom, hoy a sorok nem fogják meghaladni a 255 karaktert, sőt, nagoyn rövidek, tudom hogy van ansistring amikor egyetlen stringbe befér egy egész text fájl stb...
Tömbös megvalósítását a feladatnak azért gondoltam, mert - ha jól tudom - text fájl csak szekvenciálisan kezelhető...
Segít valaki ezt befejezni?
Külön jó lenne, ha azt is kiírná a harmadik fájlba minden sor elejére, hogy melyik fájlban volt meg a kettő közül.
Program Fajlolvas;
var
f,f2, harmadik : Text;
s : String;
f1t, f2t : Array [0..1000] of String;
sorsz : Word;
begin
Assign (f, paramstr ( 1 ) );
Assign (f2, paramstr ( 2 ) );
Assign(harmadik, paramstr (3 ) );
Reset (f);
Reset (f2);
Reset (harmadik);
sorsz := 0;
While Not Eof (f) Do
begin
ReadLn (f, s);
f1t[sorsz] := s;
Inc (sorsz);
end;
sorsz := 0;
While Not Eof (f2) Do
begin
ReadLn (f2, s);
f2t [sorsz] := s;
Inc (sorsz);
end;
Close (f);
Close (f2);
Close(harmadik);
end.
Így utánagondolva a TStringList segítségével könnyen és egyszerűen megoldható a feladat, azt hiszem...
Mindkét fájlnak két külön stringlist, feltölteni és az IndexOf segítségével lehet keresni bármely algoritmus vagy összehasonlítás nélkül...
Nem tudom hány féle egyszerű megoldása van ennek a feladatnak.
Legegyszerűbb ha van olyan adattároló ami sorrendben tárolja az elemeket és nem lehet két ugyan olyan elem. Mivel nem ismerem a Pascalt így nem tudom van e olyan.
Ha nincs akkor:
1 tömböd van és beolvasásnál csak azt rakod bele amit még nem tartalmaz, ez lényegében az első megoldás, csak neked kell ellenőrizned tartalmazza vagy sem.
Elég nyakatekert megoldást sikerült összehozni...
Szerintem SimkoL ezerszer egyszerűbben megoldaná, sőt, kapásból 5 féle megoldást tudna... :-)
Program Fajlolvas;
uses Classes, SysUtils, StrUtils;
var
f,f2, harmadik : Text;
s : String;
f1t, f2t : Array [0..1000] of String;
f1sorsz, f2sorsz, i, j : Word;
f1strl,f2strl : TStringList;
begin
f1strl.Create;
f2strl.Create;
Assign (f, paramstr ( 1 ) );
Assign (f2, paramstr ( 2 ) );
Assign(harmadik, paramstr (3 ) );
Reset (f);
Reset (f2);
Reset (harmadik);
f1sorsz := 0;
While Not Eof (f) Do
begin
ReadLn (f, s);
f1t[f1sorsz] := s;
Inc (f1sorsz);
end;
f2sorsz := 0;
While Not Eof (f2) Do
begin
ReadLn (f2, s);
f2t [f2sorsz] := s;
Inc (f2sorsz);
end;
Close (f);
Close (f2);
For i := 0 to f1sorsz Do
f1strl.add(f1t[i]);
for j := 0 to f2sorsz do
f2strl.add(f2t[j]);
For i := 0 to f1sorsz Do
begin
For j := 0 to f2sorsz Do
begin
if (f1strl.indexof(f2t[i])>0) then write(harmadik,f1t[i]);
end;
end;
Close(harmadik);
end.
A TStringList-es megoldás memóriahibával kiakadt.
Közben a tömböst megoldottam.
Program Fajlolvas;
var
f,f2, harmadik : Text;
s : String;
f1t, f2t : Array [0..1000] of String;
f1sorsz, f2sorsz, i, j : Word;
van : boolean;
begin
Assign (f, paramstr ( 1 ) );
Assign (f2, paramstr ( 2 ) );
Assign(harmadik, paramstr (3 ) );
Reset (f);
Reset (f2);
Rewrite (harmadik);
f1sorsz := 0;
While Not Eof (f) Do
begin
ReadLn (f, s);
f1t[f1sorsz] := s;
Inc (f1sorsz);
end;
f2sorsz := 0;
While Not Eof (f2) Do
begin
ReadLn (f2, s);
f2t [f2sorsz] := s;
Inc (f2sorsz);
end;
Close (f);
Close (f2);
i := 0;
Repeat
van := False;
j := 0;
Repeat
If Pos(f1t[i], f2t[j]) > 0 then van := True;
Inc (j);
Until (j = f2sorsz) or (van = True);
If Not van then WriteLn(harmadik,f2t[i]);
Inc (i);
Until (i = f1sorsz);
Close (harmadik);
end.
TStringList-el oldható meg legegyszerűbben, ha valóban text file-ról beszélünk. Amit írtál pár dolog - bár lefordul - nem fog megfelelően működni. Egy picit el kell mélyülni a Free Pascal, Delphi OOP lehetőségeiben és akkor csak pár sor az egész. ...LoadFromFile, ...SaveToFile, az IndexOf-ra ráéreztél.
Nagyon javaslom 'valahonnan' egy Delphi 7 'beszerzését', bár XP fölött picit 'érdekes' a telepítése, - a help-hez kell egy régebbi program - talán winhlp32 ?? utána kell néznem - de eszméletlen jó helppel rendelkezik. Nem teljesen minden fordul le Lazarus alatt, de az alap dolgokkal nincs gond - szerintem a konzolos alkalmazások csont nélkül.
Ha szükséged van még az én megközelítésemre is akkor szólj.
Nagyon érdekelne a Te megoldásod.
Külön jó lenne, ha a sorok elejére kiírná, hogy melyik fájlban találta meg az adott sort.
program Project2;
{$APPTYPE CONSOLE}
uses SysUtils, Classes;
var In_1, In_2, Out_1 : TStringList;
i : integer;
begin
In_1 := TStringList.Create;
In_2 := TStringList.Create;
Out_1 := TStringList.Create;
try
In_1.LoadFromFile('File1.txt');
In_2.LoadFromFile('File2.txt');
for i := 0 to In_1.Count - 1 do
if In_2.IndexOf(In_1.Strings[i]) < 0 then Out_1.Add('File1 - > '+ In_1.Strings[i]);
for i := 0 to In_2.Count - 1 do
if In_1.IndexOf(In_2.Strings[i]) < 0 then Out_1.Add('File2 - > '+ In_2.Strings[i]);
Out_1.SaveToFile('File3.txt');
finally
In_1.Free;
In_2.Free;
Out_1.Free;
end;
end.
File1:
Alma
Körte
Narancs
Szilva
Eper
Szőlő
Cseresznye
Kiwi
Banán
Őszibarack
Meggy
Málna
Sárgabarack
Nektarin
File2:
Alma
Körte
Avokadó
Narancs
Szilva
Eper
Szőlő
Ananász
Kiwi
Banán
Őszibarack
Meggy
Sárgabarack
Nektarin
Barack
Eredmény - File3:
File1 - > Cseresznye
File1 - > Málna
File2 - > Avokadó
File2 - > Ananász
File2 - > Barack
Ha erre gondoltál.
Köszönöm szépen, erre gondoltam.
Kellett neki egy {$MODE OBJFPC} beírása, hogy FPC alatt forduljon nálam.
C++ -ban, kicsit (nagyon) okádék kód lett, de működik akárhány fájlal:
class TextLine
{
struct FileCount
{
std::string fileName;
mutable size_t count = 1;
FileCount(const std::string &s) : fileName{s} {}
};
std::string m_text;
mutable std::set<FileCount> m_fileCount;
public:
TextLine(const std::string &text, const std::string &fileName) : m_text{text} { m_fileCount.insert(fileName); }
~TextLine() {}
friend bool operator<(const TextLine &lhs, const TextLine &rhs);
friend bool operator<(const FileCount &lhs, const FileCount &rhs);
void IncreaseCount(const std::string fileName) const
{
auto found = m_fileCount.find(FileCount{fileName});
if(found == m_fileCount.end())
m_fileCount.insert(fileName);
else
++found->count;
}
std::string GetText() const { return m_text; }
std::vector<std::pair<std::string, size_t>> GetFileCount() const
{
std::vector<std::pair<std::string, size_t>> v;
for(const auto i : m_fileCount)
v.push_back(std::pair<std::string, size_t>{i.fileName, i.count});
return v;
}
};
bool operator<(const TextLine &lhs, const TextLine &rhs)
{
return lhs.m_text < rhs.m_text;
}
bool operator<(const TextLine::FileCount &lhs, const TextLine::FileCount &rhs)
{
return lhs.fileName < rhs.fileName;
}
int main(int argc, char *argv[])
{
std::locale::global(std::locale{"HU"});
std::vector<std::string> file = {"file1.txt", "file2.txt"};
std::set<TextLine> set;
for(size_t i = 0; i < file.size(); i++)
{
std::ifstream ist{file[i]};
if(!ist) throw std::exception{"Nem található a fájl!"};
for(std::string s; ist >> s;)
{
TextLine tl{s, file[i]};
auto found = set.find(tl);
if(found == set.end())
set.insert(tl);
else
found->IncreaseCount(file[i]);
}
}
for(const auto &i : set)
{
std::cout << i.GetText() << ":\n";
for(const auto &k : i.GetFileCount())
std::cout << '\t' << k.first << " - " << k.second << '\n';
std::cout << '\n';
}
std::cin.get();
return 0;
}
/*
possible output:
Alma:
file1.txt - 1
file2.txt - 1
Ananász:
file2.txt - 1
Avokadó:
file2.txt - 1
Banán:
file1.txt - 1
file2.txt - 1
Barack:
file2.txt - 1
Cseresznye:
file1.txt - 1
Eper:
file1.txt - 1
file2.txt - 1
Kiwi:
file1.txt - 1
file2.txt - 1
Körte:
file1.txt - 1
file2.txt - 1
Meggy:
file1.txt - 1
file2.txt - 1
Málna:
file1.txt - 1
Narancs:
file1.txt - 1
file2.txt - 1
Nektarin:
file1.txt - 1
file2.txt - 1
Szilva:
file1.txt - 1
file2.txt - 1
Szőlő:
file1.txt - 1
file2.txt - 1
Sárgabarack:
file1.txt - 1
file2.txt - 1
Őszibarack:
file1.txt - 1
file2.txt - 1
*/
Nagyon szépen köszönöm ezt a választ is...
Bár meg tudnám tanulni a C nyelvet, de nekem az olyan átláthatatlan és bonyolult, hogy arra nincs megfelelő szó (sem több szóból álló kifejezés, hahaha). :S
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!