[C++] Problem z zadaniem z PA2002

0

Witam wszystkich userów forum :D

Mam problem z zadaniem z Potyczek Algorytmicznych z roku 2002 :D Zadanie to nosi tytuł "Imiona mrówek" - znajduje się pod http://main.edu.pl/user.phtml?op=showtask&task=z&con=PA2002 <-- tym linkiem :D

Zadanie nie jest chyba trudne prawda?:D

Mój pomysł na rozwiązanie tego zadania jest taki:

  1. Wczytuję dane :D,
  2. W pętli obliczam ilość liter każdego słowa,
  3. Jeśli jakaś litera powtarza się w słowie to jej nie liczę ( nie jestem pewien jeszcze jak to zaimplementować),
  4. Wyszukuję wyrazu, który będzie najdłuższy po modyfikacji ( punktu 3),
  5. Wypisuję wynik.

Nom i to by było tak więc teraz próbuję napisać kod.

#include <cstdio>
using namespace std;
const int ds = 20; // długość słowa.
int main()
{
 	int n,maxl=0,l=0; // zmienne n - ilość słów, maxl - najdłuższy wyraz, l - długość liter
 	char imie[ds]; // imie :D
 	
        // Wczytuję dane (1)
 	scanf("%d",&n);
 	for(int i=0;i<n;++i)
 	{
	 		scanf("%s",&imie[ds]);
        }
       
        // punkt 2 obliczam ilość lliter w wyrazach no i na tym się gubię, bo jakieś dziwne wyniki podaje
        for(int i=0;i<imie[ds];i++)
       {
	 		 if((imie[i]>='a') && (imie[i]<='z')) ++l;
       }

       // Teraz spróbujmy odczytać ilość liter w słowie
         for (int i=0;i<26;i++) 
	 { 
	 	 if (w[i]==max) 
		  printf("%c",z[i]); 
         }  

  return 0;
}
      

Co robię źle w tym liczeniu liter i jaką macie propozycje na to, żeby ten program nie liczył liter które się powtarzają??:D

0

for(int i=0;i<imie[ds];i++)
o_O
Konkretniej co to "i<imie[ds]" jest ? Sprawdzasz czy zmienna i jest mniejsza od jakiegoś randomowego miejsca w pamięci (bo jeśli tablica ma "ds" elementów to znaczy ze największy ma numer "ds-1" ze wzgledu na indeksowanie od 0)

if((imie[i]>='a') && (imie[i]<='z')) ++l;
po co taki idiotyczny warunek skoro w zadaniu jest napisane ze dane są w takiej postaci w jakiej powinny?
Szukasz problemów tam gdzie ich nie ma

Poza tym chyba nie zrozumiałeś treści zadania...
Masz wszystko związane z obliczaniem robić w jednej pętli która wykonuje się tyle razy ile ma być imion (u ciebie to jest to: for(int i=0;i<n;++i))

Reszta kodu to jest bzdura.
scanf("%s",&imie[ds]); to sie w ogóle skompilowało?

Jak sprawdzić czy sie nie powtarzają? Dwa sposoby:

  1. zapisywać unikalne literki w nowej tablicy i za każdym razem, sprawdzajac literkę, przelatywać tą tablicę i szukać czy się powtarza (jeśli nie to zliczamy i dodajemy ja do tej tablicy)
  2. sprawdzajac lierki przelatujemy tablice z naszym wyrazem (od 0 do literki na której jesteśmy) i analogicznie j.w

Jak tak patrze na ten kod to dochodze do wniosku ze to taka sklejka bez ładu i składu, a autor liczy ze ktoś się zlituje i napisze za niego, a program pewnie na jakieś zaliczenie.

#include <cstdio>

int main()
{
  const int ds = 20; // długość słowa.
  bool byla;
  int i,j,k; //iteratory
  int n; //ilość imion
  int max=0;
  int maxc;
  char imie[ds];

  scanf("%d",&n); //ilość imion

  for (i=0;i<n;i++)
    {
      scanf("%s",imie); //wczytanie imienia
      maxc=0; //ilosc liter w aktualnie analizowanym slowie
      j=0;
      byla=false; //czy literka sie powtorzyla
        while((imie[j]!=NULL)) //lecimy przez całe wpisane imie
        {
          k=0;
          while((!byla) &&k<j) //sprawdzamy wszystkie literki już przeanalizowane w poszukiwaniu powtórzeń
          {
            if (imie[j]==imie[k]) //jeśli sie powtórzyła
              byla=true; //zmienna wyrzuci nas z pętli
            k++; //a jak nie to sprawdzamy kolejną literkę
          }
          if(!byla) maxc++; //jeśli literka sie nie powtórzyła to zliczamy
          j++; //przesuwamy sie  na kolejną lierę
        }
        if (maxc>max) //jeśli max liter w słowie analizowanym przed chwilą jest większy od max dotąd
          max=maxc; //to zapisujemy nowy rekordowy wynik :P
    }
    printf("%d",max);
  return 0;
}
0

odkopuje, czy ten program dobrze dziłala np dla testu :
1
rrrrtr

0

link do zadania nie działa, więc ciężko żeby ktoś Ci pomógł

0

na pewno max długość słowa jest za mała w programie ustawiona, powinno być:
const int ds = 21; // 20 znakow + 0 na końcu
while((imie[j]!=NULL)) // ten zapis jest poprawny, jako że null jest zerem, ale daje sugestie jakby imie było tablicą wskaźników, ja bym tego NULLa zamienił na 0 lub w ogóle na while(imie[i]) lub jeszcze lepiej: zwykłego fora
linię byla=true; zamieniłbym na {byla=true; break;}., bo na cholere dalej sprawdzać

na oko program wygląda dobrze. wg. mnie jedyny problem może się pojawić (nie musi) dla stringów o długości 20

0

cóż, samo liczenie literek:
dla wejścia "q"
wyjście : 1
dla wejścia "qq"
wyjście : 1
dla wejścia "qqe"
wyjście : 2
dla wejścia "qqee"
wyjście : 2
dla weścia "qqqqeeeeffff"
wyjście : 3
dla wejścia "mikolaj"
wyjście : 7

Łapta nie wiem czy dobrze ;)

 
bool SearchIn(string qStr, char qChar, int qPlace)
{
	int len = qStr.length();
	for(int i = 0; i < len; i++)
	{
		if(i != qPlace)
			if(qStr[i] == qChar)
				return true;
		if(i == qPlace)
			return false;
	}
	return false;
}

int DiffChars(string qStr)
{
	int toRet = 0;
	int len = qStr.length();
	if(len <= 0) return 0;
	for(int i = 0; i < len; i++)
		if(!SearchIn(qStr, qStr[i], i))
			toRet++;
	return toRet;
}
0

krwq dla testu
1
rrrtr
program Shalom zwaraca 1 a powinien 2

0
#include <iostream>
#include <string>
#include <set>

int main()
{
	size_t mostUniqueChars = 0;

	int dummy;
	std::cin >> dummy;

	std::string word;
	while(std::getline(std::cin, word))
	{
		std::set<char> chars(word.begin(), word.end());
		mostUniqueChars = std::max(mostUniqueChars, chars.size());
	}
	
	std::cout << mostUniqueChars;
	
	return 0;
}
0

mi program shaloma zwrócił jeden dla:
1
rrrtr

mimo wszystko rozwiązanie reva bardziej mi się podoba pod każdym względem (no może ja bym jeszcze using namespace std dorzucił)

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