View Full Version : مشکل در جمع دو خیلی بزرگ
MiniMicro
چهارشنبه 09 آذر 1390, 19:04 عصر
سلام به همه ی دوستان گرامی کسی میتونه در نوشتن این برنامه به من کمک کنه سورسش یه مقداری اشکال داره.
من از کامپایلر بورلند استفاده می کنم.
پیشاپیش از پاسختون ممنونم.
#include<iostream.h>
int calc2str(char str1[15],char str2[15])
{
int i,n,s2n1[15],s2n2[15];
int result[15];
for(i=0;i!='\0';i++)
if(str1[i]=='0')
s2n1[i]=0;
if(str1[i]=='1')
s2n1[i]=1;
if(str1[i]=='2')
s2n1[i]=2;
if(str1[i]=='3')
s2n1[i]=3;
if(str1[i]=='4')
s2n1[i]=4;
if(str1[i]=='5')
s2n1[i]=5;
if(str1[i]=='6')
s2n1[i]=6;
if(str1[i]=='7')
s2n1[i]=7;
if(str1[i]=='8')
s2n1[i]=8;
if(str1[i]=='9')
s2n1[i]=9;
for(i=0;i!='\0';i++)
if(str2[i]=='0')
s2n2[i]=0;
if(str2[i]=='1')
s2n2[i]=1;
if(str2[i]=='2')
s2n2[i]=2;
if(str2[i]=='3')
s2n2[i]=3;
if(str2[i]=='4')
s2n2[i]=4;
if(str2[i]=='5')
s2n2[i]=5;
if(str2[i]=='6')
s2n2[i]=6;
if(str2[i]=='7')
s2n2[i]=7;
if(str2[i]=='8')
s2n2[i]=8;
if(str2[i]=='9')
s2n2[i]=9;
for(i=0;i!='\0';i++);
for(n=0;n<=i;n++)
result[n]=s2n1[n]+s2n2[n];
return result;
printstr2result(result);
}
int printstr2result(int result)
{
cout<<"result="<<result;
}
void main(void)
{
char str1[15],str2[15];
//int result;
cin>>str1>>str2;
calc2str(str1,str2);
printstr2result();
}
Ananas
چهارشنبه 09 آذر 1390, 20:08 عصر
سلام.
یه جایی اون آخرا بعد از خط for از ; اضافی استفاده کردی قبل از اینکه حلقه بعدی رو بخونه به ; میرسه که باید ; رو حذف کنی و یه مشکل دیگه ای که داره اینکه تو اون تابع طولانیه خط یکی مونده به آخرش نوشتی return result ولی خط بعدی نوشتی print و باعث میشه که print حذف بشه. باید بیاریش قبل از return. اینم کد اصلاح شده :
#include<iostream.h>
int calc2str(char str1[15],char str2[15])
{
int i,n,s2n1[15],s2n2[15];
int result[15];
for(i=0;i!='\0';i++)
if(str1[i]=='0')
s2n1[i]=0;
if(str1[i]=='1')
s2n1[i]=1;
if(str1[i]=='2')
s2n1[i]=2;
if(str1[i]=='3')
s2n1[i]=3;
if(str1[i]=='4')
s2n1[i]=4;
if(str1[i]=='5')
s2n1[i]=5;
if(str1[i]=='6')
s2n1[i]=6;
if(str1[i]=='7')
s2n1[i]=7;
if(str1[i]=='8')
s2n1[i]=8;
if(str1[i]=='9')
s2n1[i]=9;
for(i=0;i!='\0';i++)
if(str2[i]=='0')
s2n2[i]=0;
if(str2[i]=='1')
s2n2[i]=1;
if(str2[i]=='2')
s2n2[i]=2;
if(str2[i]=='3')
s2n2[i]=3;
if(str2[i]=='4')
s2n2[i]=4;
if(str2[i]=='5')
s2n2[i]=5;
if(str2[i]=='6')
s2n2[i]=6;
if(str2[i]=='7')
s2n2[i]=7;
if(str2[i]=='8')
s2n2[i]=8;
if(str2[i]=='9')
s2n2[i]=9;
for(i=0;i!='\0';i++)/////////////////////// ;
for(n=0;n<=i;n++)
result[n]=s2n1[n]+s2n2[n];
printstr2result(result);////////////////
return result;
/////////////////////////////////printstr2result(result);
}
int printstr2result(int result)
{
cout<<"result="<<result;
}
void main(void)
{
char str1[15],str2[15];
//int result;
cin>>str1>>str2;
calc2str(str1,str2);
printstr2result();
}
البته من هنوز اجراش نکردم فقط خوندمش.
موفق باشید
quiet_programmer
چهارشنبه 09 آذر 1390, 20:40 عصر
با سلام.
یکم دقت کن. این خطی که نوشتی یعنی چی؟
for(i=0;i!='\0';i++)
به i مقدار صفر دادی و اونرو با کاراکتر 0\ یا همون NULL مقایسه میکنی انتظار داری حلقه به درستی اجرا بشه؟ خوب مسلمه که مقدار i(همون صفر) با NULL(که اونم صفره) برابره و حلقه بسته به نوع دوبایتی یا چهاربایتی بودن int درسیستم شما به تعداد تقریبی 65536 و 4294967296 بار اجرا خواهد شد:متعجب:
اینو گفتم تا یکم به کدی که مینویسی دقت کنی.
ولی خب، منظورتو متوجه شدم.
اول دوتا آرایه s2n1 و s2n2 رو با کد زیر مقداردهی اولیه صفر کن.
for(i=0;i<15;i++)
s2n1[i]=s2n2[i]=0;
این خط رو جایگزین این حلقه for اولیت که اشتباه نوشته بودی کن.
for(i=0;str1[i]!='\0';i++)
برای اینکه از شر حلقه سوی خلاص بشی بلافاصله بعد از حلقه for اولی (تو کد خودت) این دستور رو داشته باش.
int Max=i;
همچنین برای for دومیت کد زیر رو جایگزین کن:
for(i=0;str2[i]!='\0';i++)
بلافاصله بعد از کد حلقه دومی دستور زیر رو داشته باش.
if(i>Max)
Max=i;
خوبه. با توجه به کدت میدونم که میفهمی داریم چکار میکنیم و چه کردیم.
حالا حلقه for سومی رو که به ; ختم شده بود(هرچند مشکل مقایسه با null رو داشت ولی در صورت اصلاح باز جواب نمیداد. من منظورت رو از قرار دادن ; در انتهای این حلقه متوجه شدم ولی این کد جواب نمیده.) رو پاک کن.
میرسیم به حلقه اصلی برای جمع.
برای جمع تو اومدی سلولهای آرایه را باهم جمع کرده و تو آرایه نتیجه قرار دادی ولی اگه یادت باشه تو دوران دبستان برای جمع چکار میکردیم، اینجور جمع نمیزدی. سلول رو جمع میزنیم اگه بزرگتر مساوی 10 میشد رقم یکان رو تو آرایه نتیجه قرار میدادیم و رقم دهگان رو Carry درنظر میگرفتیم تا با نتیجه جمع عدد بعد جمع بشه.(نگران نباش من خودم هم نفهمیدیم که چی نوشتم:متعجب: ولی کد زیر کارت رو را میندازه)
int Carry=0;
for(n=0;n<Max;n++)
{
result[n]=((s2n1[n]+s2n2[n])+Carry)%10;
Carry=((s2n1[n]+s2n2[n])+Carry)/10;
}
if(Carry!=0)
result[Max]=Carry;
چاپ هم اشتباست. Result یه آرایه است تو به صورت یه متغیر تو آرگومان رویه استفاده کردی. پس از کد زیر استفاده کن.
int printstr2result(int result[])
{
for(int i=16;i>=0;i--)
cout<<"result="<<result[i];
}
درضمن آریه result رو 16 تایی در نظر بگیر. دلیلش واضحه
نکته: همین الان یادم افتاد قبل کل این مراحل باید رشته str1 و str2 رو معکوس کنی.
یاحق.
موفق باشید/
NIMA_1981
پنج شنبه 10 آذر 1390, 00:09 صبح
برای جمع دو عدد بزرگ از این استفاده کن
#include <iostream> using namespace std;
string add (string &s1, string &s2){ int carry=0,sum,i;
string min=s1,
max=s2,
result = "";
if (s1.length()>s2.length()){
max = s1;
min = s2;
} else {
max = s2;
min = s1;
}
for (i = min.length()-1; i>=0; i--){
sum = min[i] + max[i + max.length() - min.length()] + carry - 2*'0';
carry = sum/10;
sum %=10;
result = (char)(sum + '0') + result;
}
i = max.length() - min.length()-1;
while (i>=0){
sum = max[i] + carry - '0';
carry = sum/10;
sum%=10;
result = (char)(sum + '0') + result;
i--;
}
if (carry!=0){
result = (char)(carry + '0') + result;
}
return result;
}
int main (){ string a,b;
cin >> a >> b;
cout << add (a,b)<<endl;
return 0;
}
quiet_programmer
پنج شنبه 10 آذر 1390, 12:01 عصر
با سلام.
جناب NIMA_1981 (http://barnamenevis.org/member.php?28551-NIMA_1981) ایکاش کد نمیزاشتی. هدف آموزش بود تو این تاپیک. این تاپیک قبلا به علت درخواست پروژه توسط مدیران سایت قفل شده بود. جناب MiniMicro (http://barnamenevis.org/member.php?133016-MiniMicro) مجددا تاپیک زدن با یک عنوان بهتر و ایندفعه درخواست کمک. ماهم داشتیم کمکش میکردیم تا خودش کد بنویسه. به هر حال بهتر بود که راهنمایش میکردی.
یاحق.
موفق باشید/
NIMA_1981
پنج شنبه 10 آذر 1390, 16:45 عصر
این روش که من گفتم یک دونه از روش های حل هستش که برای محاسبه عدد های بزرگ زیاد کارایی نداره البته درست کار میکنه اما سرعت این روش پایینه - بهترین روش اینکه که اعداد به مبنای دو تبدیل بشه و بعد تو مبنای دو از هم جمع یا تفریق بشه - بعضی وقت ها ممکنه با نگاه کردن به یک کد روش های بهتری به ذهنشون برسه - حتما نباید از کد بالا استفاده بشه - میتونن خودشون به شکل های دیگه هم کد ها جدید تر بنویسن -
موفق باشید
MiniMicro
پنج شنبه 10 آذر 1390, 18:58 عصر
با سلام خدمت تمام دوستان گرامی ممنون از اینکه وقت میگذارید و ما ها رو راهنمایی می کنید.
جناب quiet_programmer (http://barnamenevis.org/member.php?176670-quiet_programmer) عزیر من طبق راهنماییتون عمل کردم ولی باز یه چند تایی خطا داشت.
من سورس رو مجددا میذارم دوستان بررسی کنند تا با هم بتونیم مشکل رو رفع کنیم.
#include<iostream.h>
int calc2str(char str1[15],char str2[15])
{
int i,n,s2n1[15],s2n2[15];
int result[15];
for(i=0;i<15;i++)
s2n1[i]=s2n2[i]=0;
for(i=0;str1[i]!='\0';i++)
int Max=i;
if(str1[i]=='0') s2n1[i]=0;
if(str1[i]=='1') s2n1[i]=1;
if(str1[i]=='2') s2n1[i]=2;
if(str1[i]=='3') s2n1[i]=3;
if(str1[i]=='4') s2n1[i]=4;
if(str1[i]=='5') s2n1[i]=5;
if(str1[i]=='6') s2n1[i]=6;
if(str1[i]=='7') s2n1[i]=7;
if(str1[i]=='8') s2n1[i]=8;
if(str1[i]=='9') s2n1[i]=9;
for(i=0;str2[i]!='\0';i++)
if(i>Max)
Max=i;
if(str2[i]=='0') s2n2[i]=0;
if(str2[i]=='1') s2n2[i]=1;
if(str2[i]=='2') s2n2[i]=2;
if(str2[i]=='3') s2n2[i]=3;
if(str2[i]=='4') s2n2[i]=4;
if(str2[i]=='5') s2n2[i]=5;
if(str2[i]=='6') s2n2[i]=6;
if(str2[i]=='7') s2n2[i]=7;
if(str2[i]=='8') s2n2[i]=8;
if(str2[i]=='9') s2n2[i]=9;
for(i=0;i<=15;i++)//;
int Carry=0;
for(n=0;n<Max;n++)
{
result[n]=((s2n1[n]+s2n2[n])+Carry)%10;
Carry=((s2n1[n]+s2n2[n])+Carry)/10;
}
if(Carry<>0)
result[Max]=Carry;
return result;
printstr2result(result);
}
int printstr2result(int result[16])
{
for(int i=16;i>=0;i++)
cout<<"result="<<result[i];
}
void main(void)
{
char str1[15],str2[15],sstr1[15],sstr2[15];
//int result;
int i,n;
cin>>str1>>str2;
for(n=15,i=0;n>=0;n--,i++)
sstr1[i]=str1[n];
for(n=4,i=0;n>=0;n--,i++)
sstr2[i]=str2[n];
calc2str(sstr1,sstr2);
printstr2result();
}
quiet_programmer
شنبه 12 آذر 1390, 12:19 عصر
با سلام.
برای اینکه از شر حلقه سوی خلاص بشی بلافاصله بعد از حلقه for اولی (تو کد خودت) این دستور رو داشته باش.
ببخشید منظورم این بود که بعد بلوک دستورات for:
پس این قسمت از کدت رو به این شکل اصلاح کن.
کد خودت:
for(i=0;str1[i]!='\0';i++)
int Max=i;
if(str1[i]=='0') s2n1[i]=0;
if(str1[i]=='1') s2n1[i]=1;
if(str1[i]=='2') s2n1[i]=2;
if(str1[i]=='3') s2n1[i]=3;
if(str1[i]=='4') s2n1[i]=4;
if(str1[i]=='5') s2n1[i]=5;
if(str1[i]=='6') s2n1[i]=6;
if(str1[i]=='7') s2n1[i]=7;
if(str1[i]=='8') s2n1[i]=8;
if(str1[i]=='9') s2n1[i]=9;
کد اصلاح شده:
for(i=0;str1[i]!='\0';i++)
{
if(str1[i]=='0') s2n1[i]=0;
if(str1[i]=='1') s2n1[i]=1;
if(str1[i]=='2') s2n1[i]=2;
if(str1[i]=='3') s2n1[i]=3;
if(str1[i]=='4') s2n1[i]=4;
if(str1[i]=='5') s2n1[i]=5;
if(str1[i]=='6') s2n1[i]=6;
if(str1[i]=='7') s2n1[i]=7;
if(str1[i]=='8') s2n1[i]=8;
if(str1[i]=='9') s2n1[i]=9;
}
int Max=i;
همچنین:
کد خودت:
for(i=0;str2[i]!='\0';i++)
if(i>Max)
Max=i;
if(str2[i]=='0') s2n2[i]=0;
if(str2[i]=='1') s2n2[i]=1;
if(str2[i]=='2') s2n2[i]=2;
if(str2[i]=='3') s2n2[i]=3;
if(str2[i]=='4') s2n2[i]=4;
if(str2[i]=='5') s2n2[i]=5;
if(str2[i]=='6') s2n2[i]=6;
if(str2[i]=='7') s2n2[i]=7;
if(str2[i]=='8') s2n2[i]=8;
if(str2[i]=='9') s2n2[i]=9;
کد اصلاح شده:
for(i=0;str2[i]!='\0';i++)
{
if(str2[i]=='0') s2n2[i]=0;
if(str2[i]=='1') s2n2[i]=1;
if(str2[i]=='2') s2n2[i]=2;
if(str2[i]=='3') s2n2[i]=3;
if(str2[i]=='4') s2n2[i]=4;
if(str2[i]=='5') s2n2[i]=5;
if(str2[i]=='6') s2n2[i]=6;
if(str2[i]=='7') s2n2[i]=7;
if(str2[i]=='8') s2n2[i]=8;
if(str2[i]=='9') s2n2[i]=9;
}
if(i>Max)
Max=i;
این خط از کد رو حذف کن:
for(i=0;i<=15;i++)//;
ببخشید من هم تواین خط اشتباه کردم. خط زیر را
if(Carry<>0)
به شکل زیر اصلاح کنید:
if(Carry!=0)
خط زیر رو حذف کن و نوع بازگشتی تابعت رو void درنظر بگیر:
return result;
این خط هم اشتباه بوده اصلاح کن:
for(int i=16;i>=0;i++)
for(int i=16;i>=0;i--)
یاحق.
موفق باشید/
سید امیر حسین
یک شنبه 13 آذر 1390, 14:36 عصر
سلام
به نظرم در این کد به جای IF های متعدد میشد از یک دستور CASE استفاده کنه
اگه درست فهمیده باشم الان داره دو عدد 17 رقمی رو با هم جمع میکنه
ولی کلا میشه با 2تا حلقه FOR کارو تموم کرد
منم یه کد نوشتم براش ولی نمیدونم بزارم یا نه چون گفتن که کد رو نذارید نمیزارم اگه خواستید براتون میزارم
ولی در کل من 3تا آرایه تعریف کردم
آرایه اول و دوم اعداد رو میگیرن
و با همون حلقه جمع میشن و تو آرایه سوم ریخته میشن
بعد یه شرط براش گذاشتم که اگر جمع دو تا عدد از 9 بیشتر میشد به رقم بعدی یکی اضافه میکنه و از همون رقم 10 تا کم میکنه
نمیدونم شاید بد توضیح دادم
اگه خواستید کد رو میزارم
منم در کل حرفه ای نیستم و تازه با C++ آشنا شدم و با همون بورلندم مینویسم
quiet_programmer
دوشنبه 14 آذر 1390, 02:22 صبح
با سلام.
به نظرم در این کد به جای IF های متعدد میشد از یک دستور CASE استفاده کنهبله حتی میشه با استفاده از تابع atoi از شر ایف و کیس هم خلاص شد. ولی چون جناب MiniMicro (http://barnamenevis.org/member.php?133016-MiniMicro) اینجوری کد کرده بودن بنده چیزی در این باره نگفتم که احساس کنه پیچیده شده.
اگه درست فهمیده باشم الان داره دو عدد 17 رقمی رو با هم جمع میکنهنه. دو عدد 15 رقمی رو باهم جمع میکنه که احتمال داره مجموع دوعدد 16 رقمی باشه.
ولی کلا میشه با 2تا حلقه FOR کارو تموم کردمونده به روش کد نویسی شاید اصلا بشه با یه حلقه کار رو تموم کرد!
یاحق.
موفق باشید/
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.