Wątek przeniesiony 2018-05-12 11:00 z C/C++ przez furious programming.

Przetłumaczenie kodu z jezyka pascal na c++

0

Witam. Jestem laikiem co do języka pascal. Pomógłby ktoś przetłumaczyć ten oto kod?

var
  decisions:array of Integer;
var
  i, m, n, idol, first, second: Integer;
begin
  Read(n, m);
  SetLength(decisions, n+1);
  
  for i := 1 to m do
  begin
    Read(first, second);
    decisions[first] := -n;
    Inc(decisions[second]);
  end;
  
  idol:=0;
  
  for i := 1 to n do
    if decisions[i] = n-1 then
      idol := i;
      
  if idol = 0 then
    WriteLn('Nie ma żadnego idola')
  else
    WriteLn('Idolem jest ', idol);
end.
0

Czego konkretnie nie rozumiesz?

0

Nie znam się za bardzo na tym, a potrzebuję kod w c++ w którym się lepiej czuje :)

0

Pytam czego nie rozumiesz w podanym kodzie?

Wytłumaczę, a Ty dzięki temu będziesz mógł napisać odpowiednik w C++.

0

w "przetlumaczeniu" nie chodzilo mi o wytlumaczenie o co chodzi w tym kodzie i jak działa, bo wiem co w nim jest, tylko nie wiem jak go przepisać na c++

1

No więc zapytam po raz trzeci – czego nie rozumiesz? Której linijki nie potrafisz zapisać w C++?

0
SetLength(decisions,n+1);
decisions[first]:=-n;
    Inc(decisions[second]);
1
SetLength(decisions, n+1);

Ustawia rozmiar macierzy decisions na n+1. W C++ można to zrobić za pomocą operatora new, podając rozmiar w nawiasach kwadratowych. Różnica polega na tym, że w Pascalu macierzy dynamicznych (takich jak w pokazanym kodzie) samemu się nie zwalnia, a w C++ trzeba walnąć delete, jeśli skorzystało się z new.

Przykład znajdziesz w tym tutorialu – Dynamic memory.


decisions[first] := -n;

To jest zwyczajne wpisanie wartości do komórki tablicy. Zapis w C++ różni się nieznacznie:

decisions[first] = -n;

Inc(decisions[second]);

A to jest zwyczajna (choć starodawna) inkrementacja wartości komórki tablicy o 1. W C++ można to zapisać tak:

decisions[second] += 1;

lub za pomocą operatora ++.

0
#include <iostream>
#include <new>
using namespace std;

int main()
{

int * decisions;
int i,m,n,idol,first,second;
  decisions = new int[n+1];

  cin >> n;
  cin >> m;

   for (int i=1; m<=0; i++)

  cin >> first >> second;
    decisions[first]=-n;
    decisions[second]++;

  idol=0;
  for (int i=1; n<=0; i++ )
  if (decisions[i]=n-1){
    idol=i;
  }
  if (idol=0)
  {
      cout << "Nie ma zadnego idola" << endl;
  }
 else
    cout << "Idolem jest " << idol << endl;

 delete[] decisions;
return 0;
}

Udalo mi się to tak zapisać. Gdzie popełniłem błędy?

3
decisions = new int[n+1];
 
cin >> n;

Najpierw alokujesz pamięć dla tablicy, a następnie pobierasz wartość n – masz UB.

int i,m,n,idol,first,second;

// ...

for (int i=1; m<=0; i++)

Masz już zadeklarowaną zmienną i, ale w każdej pętli i tak deklarujesz ją ponownie.

for (int i=1; m<=0; i++)
 
cin >> first >> second;
decisions[first]=-n;
decisions[second]++;

Brakuje klamer grupujących, przez co tylko cin będzie się wykonywał w pętli.


cin >> n;
cin >> m;

AFAIR możesz to zapisać w jednej linii:

cin >> n >> m;

Przy czym nie portuj tego kodu dosłownie – w C++ możesz deklarować zmienne bądź gdzie, więc zminne, które są potrzebne w dalszej części programu, nie muszą być deklarowane na samej górze bloku kodu.

0
#include <iostream>
#include <new>
using namespace std;

int main()
{

int * decisions;
int i,m,n,idol,first,second;


  cin >> n;
  cin >> m;
  decisions = new int[n+1];

   for (int i=1; m<=0; i++)

  cin >> first >> second;
    decisions[first]=-n;
    decisions[second]++;

  idol=0;
  for (int i=1; n<=0; i++ )
  if (decisions[i]=n-1){
    idol=i;
  }
  if (idol=0)
  {
      cout << "Nie ma zadnego idola" << endl;
  }
 else
    cout << "Idolem jest " << idol << endl;

 delete[] decisions;
return 0;
}

n - liczba naturalna równa liczbie osób na przyjęciu,
m - liczba znajomości,

m par liczb naturalnych, gdzie para (x,y) oznacza znajomość, tzn że osoba x zna osobę y.

Wynik:

Odpowiedż na pytanie, czy w towarzystwie jest idol?

Przykładowe dane:

Dane1: n=6 osób, m=8

0 3 (0 zna 3)
1 2
1 3
2 0
2 3
4 3
5 1
5 3

Wynik: idolem jest 3

Tak ma to działać, jednak po wpisaniu 2 cyfry, wywala mi program. Wiesz o co chodzi?

2

Zobacz na mój wcześniejszy post – znalazłem więcej błędów i edytowałem go kilka razy.

Edit: a oprócz tego o czym napisałem w poprzednim poście, dochodzą jeszcze źle zapisane nagłówki pętli. Zwróć uwagę na to, jak w kodzie napisanym w Pascalu wyglądają pętle:

for i := 1 to m do
// ...

for i := 1 to n do
// ...

A jak wyglądają u Ciebie? Zobacz:

for (int i=1; m<=0; i++)
// ...

for (int i=1; n<=0; i++ )
// ...

To zupełnie coś innego… Te nagłówki w C++ powinny wyglądać tak:

for(int i = 1; i <= m; i++)
// ...

for(int i = 1; i <= n; i++)
// ...
0
#include <iostream>
#include <new>
using namespace std;

int main()
{

int * decisions;
int m,n,idol,first,second;


  cin >> n >> m;

  decisions = new int[n+1];

   for (int i=1; m<=0; i++)
  {


  cin >> first >> second;
    decisions[first]=-n;
    decisions[second]++;
  }
  idol=0;
  for (int i=1; n<=0; i++ )
  if (decisions[i]=n-1){
    idol=i;
  }
  if (idol=0)
  {
      cout << "Nie ma zadnego idola" << endl;
  }
 else
    cout << "Idolem jest " << idol << endl;

 delete[] decisions;
return 0;
}
1

Pętle masz źle zapisane – zobacz na poprzedni mój post (zdążyłem go już edytować). Kolejny bubel jest tu:

if (decisions[i]=n-1){

Używasz operatora przypisania, zamiast porównania – wymień = na ==.


Poza tym, te pętle w Pascalu też są złe, bo indeksują zmienną i od 1, gdy macierze dynamiczne zawsze indeksowane są od 0. I chyba z niewiedzy na ten temat powstało SetLength(decisions, n+1), zamiast po prostu n.

0
#include <iostream>
#include <new>
using namespace std;

int main()
{

int * decisions;
int m,n,idol,first,second;


  cin >> n >> m;

  decisions = new int[n+1];

   for (int i=0; i<=m; i++)
  {


  cin >> first >> second;
    decisions[first]=-n;
    decisions[second]++;
  }
  idol=0;
  for (int i=0; i<=n; i++ )



  if (decisions[i]==n-1){
    idol=i;
  }
  if (idol=0)
  {
      cout << "Nie ma zadnego idola" << endl;
  }
 else
    cout << "Idolem jest " << idol << endl;

 delete[] decisions;
return 0;
}


2

W dalszym ciągu nagłówki pętli są złe (ich indeksowanie i warunki zakończenia).

Zobacz na poniższy kod – powinien śmigać, chyba że coś jeszcze przeoczyłem:

#include <iostream>
#include <new>

using namespace std;
 
int main()
{
  int * decisions;
  int n, m, first, second;
 
  cin >> n >> m;
  decisions = new int[n];
 
  for(int i = 0; i < m; i++)
  {
    cin >> first >> second;
    decisions[first] = -n;
    decisions[second]++;
  }
  
  int idol = 0;
  
  for(int i = 0; i < n; i++) 
    if (decisions[i] == n - 1)
      idol = i;

  if(idol == 0)
    cout << "Nie ma zadnego idola" << endl;
  else
    cout << "Idolem jest " << idol << endl;
 
  delete[] decisions;
  return 0;
}
0
#include <iostream>
#include <new>
using namespace std;

int main()
{

int * decisions;
int m,n,idol,first,second;


  cin >> n >> m;

  decisions = new int[n+1];

   for (int i=1; i<=m; i++)
  {


  cin >> first >> second;
    decisions[first]=-n;
    decisions[second]++;
  }
  idol=0;
  for (int i=1; i<=n; i++ )



  if (decisions[i]==n-1){
    idol=i;
  }
  if (idol==0)
  {
      cout << "Nie ma zadnego idola" << endl;
  }
 else
    cout << "Idolem jest " << idol << endl;

 delete[] decisions;
return 0;
}

Chyba juz poprawnie wszystko działa

1

W dalszym ciągu nie rozumiem dlaczego alokowanych jest n+1 komórek tablicy, zamiast po prostu n. W konsekwencji czego pętle muszą być indeksowane od 1 do n, zamiast od 0 do n-1. Pierwsza komórka decisions nigdy nie jest używana, zarówno w Pascalu, jak i w C++.

W poprzednim poście podałem kod eliminujący to udziwnienie.

0

Przykład znajdziesz w tym tutorialu – Dynamic memory.

Skoro tyle problemów jest z alokowaniem dynamicznym pamięci dla tablicy,
może warto spojrzeć na std::vector, a w wolnej chwili postarać się zrozumieć
oprator new.

0

@YooSy: na pewno warto, jednak wszystko po kolei. Tego typu wątki z reguły zawierają kody, które nie mają wylądować na produkcji, a jedynie nauczyć podstaw programowania. Bo najpierw należy się nauczyć obsługi tak prostych typów danych, zanim zacznie się przygodę z obiektowością.

Dlatego staram się rozwiązać problem (tu: przełożyć kod 1:1), zamiast tworzyć nowych.

0

a co ze sprawdzeniem czy przy zapisie index nie wychodzi poza zakres?

0

Może ja ciężko myślę po sobocie, ale jaki jest cel linii decisions[first]=-n;?

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