PDA

View Full Version : کمک در حل یک مسئله



lvlina_r
چهارشنبه 28 بهمن 1388, 11:40 صبح
برنامه ای نوشتم که داده هایی را از تو فایل می خونه، هدفش تقسیم پول بین جندین نفره، مثلا باید به ورودی
5
dave
laura
owen
vick
amr
dave
200 3
laura
owen
vick
owen
500 1
dave
amr
150 2
vick
owen
laura
0 2
amr
vick
vick
0 0

خروجی

amr -150
dave 302
laura 66
owen -359
vick 141

را بده
من این کد را نوشتم

#include<iostream>
#include<fstream>
#include<map>
#include<string>
usingnamespace std;
int main()
{
ifstream fin("gift1.txt" , ios::in );
ofstream fout("gift2.txt" , ios::out) ;
int n ,i , money ,cash ,num;
string s , name ;
fin>>num ;
map <string,int> m;

for(i=0 ; i<num ; i++)
{
fin>>s;
m.insert(pair<string,int>(s,0));
}

while ( !(fin.eof() ) )
{
fin >> s ;
fin >> cash ;
fin >> n ;
int part;
if(n!=0)
part=cash/n;
else
part=0;
m[s] -= part * n;


for ( i=0 ; i<n ; i++ )
{
fin >> name ;
m.find(name)->second += part ;
}

}
map<string,int>::iterator it;
for ( it=m.begin() ; it != m.end(); it++ )
fout << (*it).first << " " << (*it).second << endl;

fin.close();
fout.close();
return 0;

}

ولی 2 تا مشکل داره
1. بعضی وقتا خروجی ها اشتباه می شه
2.خروجی را sort می کنه چون از map استفاده کردم
کسی می تونه کمکم کنه؟؟؟؟؟؟؟؟

amin1softco
چهارشنبه 28 بهمن 1388, 12:38 عصر
یک مشکلی وجود داره مپ باید داده کی ( key ) اون یکتا باشه ولی مقدار پول می تونه تکراری باشه و برای همین فکر کنم قاطی می کنه چرا شما از لیست پیوندی استفاده نمی کنید؟
ولی اگر همچنان دوست دارید از مپ استفاده کنید باید از multimap استفاده کنید که کی های متفاوت را ساپورت می کنه

lvlina_r
چهارشنبه 28 بهمن 1388, 13:18 عصر
یک مشکلی وجود داره مپ باید داده کی ( key ) اون یکتا باشه ولی مقدار پول می تونه تکراری باشه و برای همین فکر کنم قاطی می کنه چرا شما از لیست پیوندی استفاده نمی کنید؟
ولی اگر همچنان دوست دارید از مپ استفاده کنید باید از multimap استفاده کنید که کی های متفاوت را ساپورت می کنه

می شه بیشتر توضیح بدین؟؟ مشکل sort با mulitimap حل می شه؟؟؟
اگه بخواوم از لیست استفاده کنم چه مزیتی داره؟؟

amin1softco
چهارشنبه 28 بهمن 1388, 13:27 عصر
اگه از لیست استفاده کنید مشکله sort برطرف میشه و اگه از مولتی مپ استفاده کنید مشکل قاطی کردنش برطرف می شه
ولی یک راه اینه که وقتی دارید تو فایل خروجی می نویسید راندوم اینکار رو بکنید که احتیاجی به لیست هم نباشه

lvlina_r
چهارشنبه 28 بهمن 1388, 14:13 عصر
یعنی چی رندوم؟؟ خودش سورت می کنه ....
می شه در مورد multi map هم یکم توضیح بدین، مرسی....

amin1softco
چهارشنبه 28 بهمن 1388, 18:46 عصر
منظورم از رندوم همون حالت تصادفیه یعنی به جای یک فور ساده یک حلقه بنویسیم که تا زمانی که خروجی ها کامل نشده ادامه داشته باشه و i هم راندوم محاسبه بشه و با یک شرط به فایل انتقال داده بشه
مولتی مپ تفاوت زیادی با مپ نداره لینک زیر را ببینید:
http://www.cplusplus.com/reference/stl/multimap/
مثل خود مپ کار می کنه فقط این مزیت رو داره که کی ها می تونند تکراری هم باشند همین

lvlina_r
چهارشنبه 28 بهمن 1388, 23:21 عصر
ببینید کلید های تکراری نداریم که بخوایم از multimap استفاده کنیم، پس مشکل اینجا نیست....
واسه سورتم نشدنشم اینراهی که شما می گین یعنی بریم محل چاپ خروجی را پیدا کنیم و اونجا چاپ کنیم؟؟؟ اینجوری که خیلی سخت می شه

amin1softco
پنج شنبه 29 بهمن 1388, 00:08 صبح
من چی فکر می کردم چی شد من فکر می کردم که می خواهید سورت نباشه در حالی که مشکل شما اینجاست که مپ بر اساس کی ها سورت می کنه و شما بر اساس داده ها می خواهی این کار را انجام بدی درسته یا بازم اشتپ کردم ؟؟؟؟؟؟؟

lvlina_r
پنج شنبه 29 بهمن 1388, 10:08 صبح
بازم اشتباه کردین، من می خواستم به همون ترتیبی که داده ها را از ورودی می خونه در خروجی امک چاپ کنه، که این مشکلم حل شد، حالا مشکل دومم
چرا بعضی از خروجی هام اشتباهه....
مثلا با این ورودی
10
mitnik
Poulsen
Tanner
Stallman
Ritchie
Baran
Spafford
Farmer
Venema
Linus
mitnik
300 3
Poulsen
Tanner
Baran
Poulsen
1000 1
Tanner
Spafford
2000 9
mitnik
Poulsen
Tanner
Stallman
Ritchie
Baran
Farmer
Venema
Linus
Tanner
1234 1
Poulsen
Stallman
536 3
Farmer
Venema
Linus
Ritchie
2000 1
mitnik
Baran
79 2
Tanner
Farmer
Farmer
0 0
Venema
12 9
mitnik
Poulsen
Tanner
Stallman
Ritchie
Baran
Spafford
Farmer
Linus
Linus
1000 1
mitnik
از من این خروجی را می ده
mitnik 3923
Poulsen 557
Tanner 128
Stallman -311
Ritchie -1777
Baran 245
Spafford -1997
Farmer 440
Venema 391
Linus -1599
در صورتی که باید این خروجی را بده

mitnik 2923
Poulsen 557
Tanner 128
Stallman -311
Ritchie -1777
Baran 245
Spafford -1997
Farmer 440
Venema 391
Linus -599

amin1softco
پنج شنبه 29 بهمن 1388, 10:38 صبح
اونوقت من می گم شما باید از مولتی مپ استفاده کنید شما می گی نه خوب این ورودی شما عدد تکراری داره یعنی کی های تکراری 0 0 دو تا عدد تکرایه 1 1 1 سه عدد تکراریه خوب مپ قاطی می کنه دیگه

lvlina_r
پنج شنبه 29 بهمن 1388, 11:18 صبح
آخه کلید من اسم هاست ، نه اعداد ...، اسم ها که تکراری نداره.........

amin1softco
پنج شنبه 29 بهمن 1388, 11:53 صبح
ولی مپ به طور پیش فرض همون عدد ها رو کلید قرار میده نه داده ها ی رشته ایی را

lvlina_r
پنج شنبه 29 بهمن 1388, 11:59 صبح
یعنی چی؟؟ مگه map<string,int> رشته کلید نمی شه؟؟
مثلا من با m[s] به عنصر مورد نظر دست پیدا می کنم، پس رشته کلیدمه ....

lvlina_r
پنج شنبه 29 بهمن 1388, 12:47 عصر
ببینید من متوجه مشکلش شدم، ولی نمی دونم چطوری حل کنم؟ یک بار اضافی تو حلقه ی while می ره، یعنی دوبار
Linus
1000 1
mitnik
را انجام می ده....، خواهشا یکی کمکم کنه........

amin1softco
پنج شنبه 29 بهمن 1388, 12:51 عصر
خوب اینجوری که شما می گی پس مشکل از کجاست نمی تونه از نوع int باشه long بزارید بازم قاطی می کنه؟؟؟؟:متفکر:
می شه سورس آخری رو بزارید تا یکم بیشتر روش تمرکز کنیم شاید به جایی رسیدیم

lvlina_r
پنج شنبه 29 بهمن 1388, 13:02 عصر
ببینید برنامه درسته، فقط شرط while یه بار اضافیه


#include<iostream>
#include<fstream>
#include <map>
#include <string>
using namespace std;
int main()
{
ifstream fin("gift1.txt" , ios::in );
ofstream fout("gift2.txt" , ios::out) ;
int n ,i , money ,cash ,num;
string s , name ;
fin>>num ;
map <string,int> m;
string * esm=new string[num];
for(i=0 ; i<num ; i++)
{
fin>>s;
esm[i]=s;
m.insert(pair<string,int>(s,0));
}

while ( !(fin.eof() ) )
{
fin >> s ;
fin >> cash ;
fin >> n ;
int part;
if(n!=0)
part=cash/n;
else
part=0;
m[s] -= part * n;


for ( i=0 ; i<n ; i++ )
{
fin >> name ;
if(fin.eof())
break;
m.find(name)->second += part ;
}

}


for(int i=0 ; i<num;i++)
fout << esm[i] << " " << m.find(esm[i])->second << endl;
fin.close();
fout.close();
return 0;

}

amin1softco
پنج شنبه 29 بهمن 1388, 13:26 عصر
فکر کنم خودت بهتر مشکلش رو می دونستی فکر کنم درست شد :


#include<iostream>
#include<fstream>
#include<map>
#include<string>
using namespace std;
int main()
{
ifstream fin("gift1.txt" , ios::in );
ofstream fout("gift2.txt" , ios::out) ;
int n ,i , money ,cash ,num;
string s , name ;
fin>>num ;
map <string,int> m;
string * esm=new string[num];
for(i=0 ; i<num ; i++)
{
fin>>s;
esm[i]=s;
m.insert(pair<string,int>(s,0));
}

while (true)
{

fin >> s ;
fin >> cash ;
fin >> n ;
if(fin.eof())break;
int part;
if(n!=0)
part=cash/n;
else
part=0;
m[s] -= part * n;


for ( i=0 ; i<n ; i++ )
{
fin >> name ;
if(fin.eof())
break;
m.find(name)->second += part ;
}

}


for( i=0 ; i<num;i++)
fout << esm[i] << " " << m.find(esm[i])->second << endl;
fin.close();
fout.close();
return 0;

}

lvlina_r
پنج شنبه 29 بهمن 1388, 13:36 عصر
مرسیییییی، درست شد:تشویق:
ولی یه سوال، مگه while() چه اشکالی داشت؟؟

amin1softco
پنج شنبه 29 بهمن 1388, 13:44 عصر
چون وقتی آخرین اطلاعات را از فایل می خونه شرط ویل برقرار می شه و لی ویل در ابتدای حلقه بعدی این شرط را چک می کنه و مشکل ایجاد میشه فکر کنم از do while استفاده کنید بازم مشکل رفع بشه