PDA

View Full Version : Въпрос за свързан списък C++



m.dimitrov
01-08-2019, 13:26
Здравейте, имам ето това задание:


Големи числа се наричат цели положителни числа с К цифри. Големите цели числа могат да се представят с помощта на линеен едносвързан списък, всеки елемент на който съдържа точно една цифра от числото. Дадени са две големи цели числа N1 и N2 (до 100 цифри). Да се напишат програмни фрагменти за :

a. Представяне на числата чрез списъци;

b. Сумиране на две големи цели числа.



Бях го направил с две функции create1 и create2 и две променливи N1 и N2, но професорката иска да е само един и колкото числа искам да въведа толкова пъти да извикам един и същ create. Опитах по този начин но при започване на въвеждането на второто число програмата блокира. Бих бил благодарен ако някой помогне.



Ето и до къде съм стигнал.



#include <iostream>
using namespace std;

struct chislo{
int N;
chislo* next;
};
typedef chislo* Point;
Point Head;

void Create(Point &Head) {
Point Last, P; Last=NULL;
int brc=0;
int br=0;
cout<<"Колко цифри ще е числото?: ";
cin>>br;
while (brc != br) {
P = new chislo;
brc++;
cout << brc <<" цифра на числото: ";
cin >> P->N;
P->next=NULL;
if (Head == NULL) Head = P;
else Last->next = P;
Last = P;
}
}

void Traverse(Point P){
cout<<"Числото е:";
while (P !=NULL) {
cout<<P->N;
P = P->next;
}
cout<<endl;
}

int main() {
system("chcp 1251");
Point Head = NULL;
Create(Head);
Create(Head);
Traverse(Head);
Traverse(Head);
}

nqmamNervi
01-08-2019, 18:47
един начин да провериш къде ти гърми кода е да закоментираш и разкоментираш ред по ред
ако след като закоментираш даден ред програмата работи, значи там е проблема
другия вариант е да ползваш дебъгер от рода на gdb/gdbtui/някое IDE
в твоя случай проблемът е там, че при второто извикване на ф-ята Create Head вече не е NULL
и кода се чупи на тази проверка
if (Head == NULL) Head = P; (прескача тази проверка)
else Last->next = P; (влиза тук)

защото и Last по-нагоре е занулен и програмата се опитва да достъпи елемент на нещо, което е NULL.
вариант ти е в началото на ф-ята create да проверяваш дали Head е NULL и ако не е - Last трябва да бъде последния елемент от свързания списък - (правиш си някакъв while цикъл с условие Head->next != NULL, така намираш последния елемент)

http://learn-c.org/en/Linked_lists - това е на C, но са обяснени добре
има доста информация в интернет

успех

m.dimitrov
01-09-2019, 12:34
Благодаря за насоките, но успях да го направя по този начин и спoред преподавателя функцията create вече е вярна.
Ето и кода:

#include <iostream>
using namespace std;

struct chislo{
int N;
chislo* next;
};
typedef chislo* Point;
Point Head1,Head2;

void Create(Point &Head) {
Point Last, P;
int brc=0;
int br=0;
cout<<"Колко цифри ще е числото?: ";
cin>>br;
while (brc != br) {
P = new chislo;
brc++;
cout << brc <<" цифра на числото: ";
cin >> P->N;
P->next=NULL;
if (Head == NULL) Head = P;
else Last->next = P;
Last = P;
}
}

int Traverse(Point P){
int ch=0;
while (P !=NULL) {
ch=(ch*10)+P->N;
P = P->next;
}
return ch;
}


int main() {
system("chcp 1251");
int sum=0;
Point Head1 = NULL;
Point Head2 = NULL;
Create(Head1);
Create(Head2);
sum=Traverse(Head1)+Traverse(Head2);
cout<<"Сумата на числата е: "<<sum<<endl;
}

nqmamNervi
01-09-2019, 19:05
да, това е в пъти по-лесно
решил съм, че се иска да има някаква връзка м/у тези числа по някаква причина

обърнах внимание, че Traverse връща int, тоест макс. стойност на числото е максималната стойност на int
като за демо на списъци става и най-вероятно никой няма да обърне внимание на това
но ако пуснеш повечко числа, сумирането няма да работи

m.dimitrov
01-09-2019, 22:18
Точно това ми каза и преподавателят когато му я изпратих. Цитирам:

"Сумирането на двете големи числа не трябва да става по този начин. Вие, от списъка получавате всяко от числата като integer число и след това сумирате 2-те integer-числа. Идеята на представянето на число чрез списък е, че то е толкова голямо, че не може да се "събере" в integer-типа. Сумирането трябва да стане обхождайки двата списъка (т.е 2-те числа) паралелно, започвайки отзад-напред и сумирайки цифра по цифра. Разбира се трябва и допълнитела променлива за текущия пренос."

Но нямам идея как да го реализирам в код.

dreamwalker
01-11-2019, 22:01
Питай в Stack Overflow, вероятността да получиш помощ там е доста по-висока.

Впрочем откога C++ разпознава кирилица, гледам, че output-а ти е на български.

nqmamNervi
01-12-2019, 18:53
Точно това ми каза и преподавателят когато му я изпратих. Цитирам:

"Сумирането на двете големи числа не трябва да става по този начин. Вие, от списъка получавате всяко от числата като integer число и след това сумирате 2-те integer-числа. Идеята на представянето на число чрез списък е, че то е толкова голямо, че не може да се "събере" в integer-типа. Сумирането трябва да стане обхождайки двата списъка (т.е 2-те числа) паралелно, започвайки отзад-напред и сумирайки цифра по цифра. Разбира се трябва и допълнитела променлива за текущия пренос."

Но нямам идея как да го реализирам в код.

в общи линии идеята е да представиш голямото число като отделни цифри и да ги сумираш както го правиш на лист хартия - събираш двете цифри и си пазиш едното на ум в някаква променлива, която добавяш към следващата сума.
новата функция трябва също да връща такова голямо число/или да попълва някаква резултатна променлива (за всяка сума си попълваш елемент от новосъздадения тип, както правиш в create).
аз лично бих използвал тази
<https://www.geeksforgeeks.org/circular-linked-list/> структура от данни, както и бих пазил някъде броя на цифрите на числото, за да знам кое е по-голямото.