Listy jednokierunkowe- porównywanie dwóch list.

Odpowiedz Nowy wątek
2014-03-02 00:23

Rejestracja: 6 lat temu

Ostatnio: 6 lat temu

0

Cześć, mam pewien problem z przedstawioną niżej funkcją, po prostu nie działa- pojawia się komunikat o błędzie SIGSEGV, ale nie wiem dlaczego, bo wydaje mi się, że nie ma problemu z alokacją pamięci. Przedstawiona przeze mnie funkcje porównuje dwa listy kiednokierunkowe ze wskaźnikiem na pierwszy element, gdy znajdzie takie same węzły, usuwa je zarówno z jednej listy, jak i z drugiej. I tak dalej, aż druga lista pozostanie pusta.
(Funkcja remove- usuwa dany węzeł, funkcja change- zmienia ostatni węzeł według schematu).
Proszę o pomoc i z góry dziękuję za wszystkie wskazówki.

void crossout(node *&head1, node *&head2)
{
    node *temp1=head1;
    node *temp2=head2;
    while(head2!=NULL)
{
    while(temp2!=NULL)
    {
        while(temp1!=NULL)
        {
            if(temp1->x==temp2->x)
            {

                remove(head1,temp1);
                remove(head2,temp2);
                temp1=head1;
                temp2=head2;

            }
            else{
            temp1=temp1->next;  
            }
        }temp2=temp2->next; 
        temp1=head1;
    }
    change(head1);
    temp1=head1;
    temp2=head2;
}
} 

Pozostało 580 znaków

2014-03-02 00:49

Rejestracja: 14 lat temu

Ostatnio: 3 dni temu

1

Sformatuj kod po ludzku oraz podaj treść funkcji remove() i change().


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2014-03-02 09:42

Rejestracja: 6 lat temu

Ostatnio: 6 lat temu

0

Co to znaczy "sformatuj kod po ludzku"? Co tu jest nie tak?
Remove:


void remove(node *&head, node *x)
{
    if(head!=x)
    {
        node *temp=head;
        while(temp->next!=x)    temp=temp->next;
        temp->next=x->next;
        delete x;
    }
    else
    {
        node *temp=head;
        if(temp==NULL) return;
        head=temp->next;
        delete temp;
    }
}

change

void change(node *&head)
{
    node *temp=head;
    while(temp->next!=NULL)
    {
        temp=temp->next;
    }
    switch(temp->x)
    {
        case 'M': {removeLast(head);addBack(head,'D');addBack(head,'D');}break;
        case 'D': {removeLast(head);addBack(head,'C');addBack(head,'C');addBack(head,'C');addBack(head,'C');
                addBack(head,'C');}break;
        case 'C': {removeLast(head);addBack(head,'L');addBack(head,'L');}break;
        case 'L': {removeLast(head);addBack(head,'X');addBack(head,'X');addBack(head,'X');addBack(head,'X');
                addBack(head,'X');}break;
        case 'X': {removeLast(head);addBack(head,'V');addBack(head,'V');}break;
        case 'V': {removeLast(head);addBack(head,'I');addBack(head,'I');addBack(head,'I');addBack(head,'I');
                addBack(head,'I');}break;
        default: return;break;
}
} 
Pewnie chodzi o nawiasy klamrowe powstawiane jak popadnie i dziwne wcięcia. - szweszwe 2014-03-02 09:57

Pozostało 580 znaków

2014-03-02 10:17

Rejestracja: 14 lat temu

Ostatnio: 3 dni temu

0

W kodzie masz użyte kolejne funkcje removeLast() i addBack() podaj ich treść również.
Podpowiadam że jeżeli oni wywołują jakieś inne funkcje to ich również należy podać.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2014-03-02 10:36

Rejestracja: 6 lat temu

Ostatnio: 6 lat temu

0
void removeLast(node *&head)
{
    node *temp=head;
    if(temp==NULL) return;
    if(temp->next!=NULL)
    {
        while(temp->next->next!=NULL)   temp=temp->next;
        delete temp->next;
        temp->next=NULL;
    }
    else
    {
        delete temp;
        head=NULL;
    }
} 
void addBack(node *&head,char x)
{
    node *N=new node;
    N->x=x;
    N->next=NULL;
    node *temp=head;
    if(temp!=NULL)
    {
        while(temp->next!=NULL)
        {
            temp=temp->next;
        }
        temp->next=N;
    }else
    {
        head=N;
    }
} 

struktura:


{
    char x;
    node *next;
};

Pozostało 580 znaków

2014-03-02 10:51

Rejestracja: 14 lat temu

Ostatnio: 3 dni temu

0

to: case 'M': {removeLast(head);addBack(head,'D');addBack(head,'D');}break;
zamień na: case 'M': {temp->x='D';addBack(head,'D');}break;
Analogicznie resztę.

Usuwanie z końca oraz dodawanie na koniec listy jednokierunkowej to poroniony pomysł no chyba że trzymasz wskaźnik na ostatni element.
Usuwanie ze środka listy jednokierunkowej to zawsze poroniony pomysł - potrzebna lista dwukierunkowa.
Wytłumacz mi czemu nie działasz na zwykłym string'u - tak jak zorganizowałeś listę na string'u będzie o wiele krótszy kod a przy tym o wiele szybszy.
Aby zrobić porządnie na strukturach potrzebujesz:

struct node { char x; node *next,*prev; }
struct list { node *head,*tail; }

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 2x, ostatnio: _13th_Dragon, 2014-03-02 10:57

Pozostało 580 znaków

2014-03-02 12:45

Rejestracja: 8 lat temu

Ostatnio: 6 godzin temu

0

Zamień:

while(head2!=NULL)

Na:

if(head2!=NULL)

lub zrób coś żeby head2 się zmieniało.


Szacuje się, że w Polsce brakuje 50 tys. programistów
edytowany 1x, ostatnio: vpiotr, 2014-03-02 12:46

Pozostało 580 znaków

2014-03-02 13:46

Rejestracja: 6 lat temu

Ostatnio: 6 lat temu

0

_13th_Dragon: to faktycznie przy tym switchu troszkę głupio zrobiłem. Ale już to poprawiłem, co do reszty, próbowałem z listą dwukierunkową- faktycznie usprawni to mój program, lecz mimo tego, coś jest nie tak w funkcji crossout (tak sądzę). Nie działa ona tak jak bym tego chciał.
vpiotr: wydaje mi się, że ten while jest tam ok. Bo po właściwym wykonaniu operacji, lista nr 2 powinna zostać pusta i wtedy opuszczamy pętle.

Pozostało 580 znaków

2014-03-02 15:41

Rejestracja: 6 lat temu

Ostatnio: 6 lat temu

0

To po zamianie na listy na stringa wygląda to tak:

void change(string roman)
{

    switch(roman[roman.length()-1])
    {
        case 'M': {roman[roman.length()-1]='D';roman+='D';}break;
        case 'D': {roman[roman.length()-1]='C';roman+='C';roman+='C';roman+='C';roman+='C';}break;
        case 'C': {roman[roman.length()-1]='L';roman+='L';}break;
        case 'L': {roman[roman.length()-1]='X';roman+='X';roman+='X';roman+='X';roman+='X';}break;
        case 'X': {roman[roman.length()-1]='V';roman+='V';}break;
        case 'V': {roman[roman.length()-1]='I';roman+='I';roman+='I';roman+='I';roman+='I';}break;
        default: return;break;
}
}
string crossout(string rom1, string rom2)
{
    while(rom2.length()>0)
    {
    for(int i=0;i<rom1.length();i++)
    {
        for(int j=0;rom2.length();j++)
        {
            if(rom1[i]==rom2[j])
            {
                rom1.erase(i);
                rom2.erase(j);
            }
        }
    }
    change(rom1);
    }
    return rom1;
}

Ale niestety wciąż nie działa.

edytowany 1x, ostatnio: DJames, 2014-03-02 16:07

Pozostało 580 znaków

2014-03-02 20:16

Rejestracja: 14 lat temu

Ostatnio: 3 dni temu

0
  1. zamiast: roman[roman.length()-1]='D'; użyj: roman.back()='D';
  2. do change() przekazuj przez referencje
  3. po erase() nie powinieneś inkrementować pozycji.

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2014-03-02 20:25

Rejestracja: 6 lat temu

Ostatnio: 6 lat temu

0
  1. jak wpiszę roman.back()='D'; to pojawia sie błąd "[Error] 'std::string' has no member named 'back'"
  2. zmieniłem funckja change() na:
    void change(string roman)
    {
    if(roman[roman.length()-1]=='M')
    {
        roman[roman.length()-1]='D';
        roman+='D';
    }
    else if(roman[roman.length()-1]=='D')
    {
        roman[roman.length()-1]='C';
        roman+='C';
        roman+='C';
        roman+='C';
        roman+='C';
    }
    else if(roman[roman.length()-1]=='C')
    {
        roman[roman.length()-1]='L';
        roman+='L';
    }
    else if(roman[roman.length()-1]=='L')
    {
        roman[roman.length()-1]='X';
        roman+='X';
        roman+='X';
        roman+='X';
        roman+='X';
    }
    else if(roman[roman.length()-1]=='X')
    {
        roman[roman.length()-1]='V';
        roman+='V';
    }
    else if(roman[roman.length()-1]=='V')
    {
        roman[roman.length()-1]='I';
        roman+='I';
        roman+='I';
        roman+='I';
        roman+='I';
    }
    else
    {
        return;
    }
    } 

    Wiem, troszkę miejsca zajmuję. I tu jak przekazuję referencje- to mi w ogóle nie działa.

  3. Tzn, że jak inkrementowac pozycji? W jaki sposób mógłbym to zastąpić?

Dzięki za rady.

edytowany 2x, ostatnio: DJames, 2014-03-02 20:26

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0