Jump to content

char masīvu salīdzināšana


Guest
 Share

Recommended Posts

c++

 

ir šāda funkcija,kas pārbauda,vai divi char masīvi ir vienādi.

 

int cs(char *a, char *b)

{

for (int i=0; i<=50;i++)

if (a!=b) return 0;

return 1;

};

 

Vai a!=b un !a==b šajā gadījumā ir viens un tas pats?

Link to comment
Share on other sites

Slikta funkcija. Ja tu programmē C++, tad lieto std::equal funkciju:

#include <algorithm>

if (std::equal(a, a+50, b)) { a un b ir vienādi masīvi ... } else { nav vienādi }

Bet atbilde uz tavu jautājumu ir nē, tas nav viens un tas pats. ! ir lielāka prioritāte nekā ==. Tāpēc vispirmis izpildīsies !a un tad tā rezultāts salīdzināsies ar b. Lieto iekavas, lai mainītu prioritātes: if (!(a == b)) ...

 

C++'ā arī eksistē bool tips ar true un false vērtībām. Nevajag lietot 0 un 1.

Labots - bubu
Link to comment
Share on other sites

Un, ja Tu programmē iekš C, tad ir funkcija strncmp(a, b, 50). Un, nē, tas nav viens un tas pats. Sanāk šitā:

 

a != b

 

salīdzina, vai abi chari ir vienādi.

 

!a == b

 

! šajā gadījumā izpildās pirmais, un strādā kā boolean operators. T.i. a tiek uztverts kā true/false tipa mainīgais, un tam uzlikts NOT. Pēc tam šī boolean vērtība tiek salīdzināta ar b, arī to uztverot kā boolean vērtību. T.i. piemēram, ja a un b abi būtu simbols "A" (skaitliskā vērtība 65), tad !a būtu false, bet b būtu true, un visas izteiksmes vērtība - false.

Link to comment
Share on other sites

to bubu:

 

namespace std nevaru izmantot. Varu lietot tikai stdio.h un stdlib.h bibliotēkas.

 

Varbūt ir kāda līdzīga funkcija tevis minētajai no šīm bibliotēkām?

 

Kas tieši šajā funkcijā ir slikts?

 

Bool tipa mainīgos kompilators tāpat realizē kā int. Tur nav pilnīgi nekāda nekāda starpība.

 

to Vilx-:

 

Paldies!

Labots - Guest
Link to comment
Share on other sites

Iekš <string.h> ir manis minētā strncmp() funkcija. Slikts ir tas, ka nevajag izgudrot pašam to, ko jau ir gatavu uztaisījuši cilvēki daudz gudrāki par Tevi, un arī daudz vairāk pārbaudījuši, ka tas strādā labi un pareizi.

 

Bool vs Int - Realizē varbūt jā, bet salīdzināšana gan nenotiek tāpat. Salīdzinot kā integerus, 12 != 34, bet salīdzinot kā booleanus, 12 == 34.

Link to comment
Share on other sites

to Vilx-:

 

Strncmp() ir jāpadod par 1 argumentu (garumu) vairāk. Man programmā salīdzināmie masīvi vienmēr būs garumā 50. Un man neinteresē, kurš ir garāks vai īsāks, tikai vai tie ir vienādi. Vai arī šādā gadījumā Tu labāk ieteiktu lietot strncmp(), nevis šādu finkciju:

 

bool cs(char *a, char *b)

{

for (int i=0; i<=50;i++)

if (a!=b) return false;

return true;

};

 

?

Link to comment
Share on other sites

Jā, es lietotu strncmp. Un padotu to paplidus argumentu 50. Es to lietotu tāpēc, ka:

  • Tā dara tieši to pašu, ko Tava funkcija;
  • Man nebūtu jāpūlas rakstīt savu funkciju;
  • Man nebūtu jāriskē/jāmeklē kļūdas savā funkcijā;
  • Šī funkcija ir rakstīta asemblerā un izpildās ātrāk nekā šāda pašrakstīta funkcija. Lai arī šis ir diezgan nenozīmīgi, jo šādas funkcijas reti ir lēnā vieta programmā.

Link to comment
Share on other sites

problēma tāda,ka string.h nevaru lietot.

 

pieejamas tikai:

#include "stdio.h"

#include "stdlib.h"

Link to comment
Share on other sites

Ko ta tā? Mājasdarbs, vai? Nu, ja tā, tad es neredzu sākotnējai funkcijai nekādas vainas.

Link to comment
Share on other sites

Jā, mājasdarbs, kurš tiek pārbaudīts automātiskā programmu testēšanas sistēmā, kur kompilators lieto tikai "stdio.h" "stdlib.h"..

Link to comment
Share on other sites

OK. Kā jau teicu, nav ne vainas sākotnējai funkcijai. Tikai... ā, viens sīkumiņš. Ja Tev masīvā ir 50 elementi, tad tiem indeksi ir no 0 līdz 49. Ciklā Tu pārbaudi arī 50. elementu, kas jau sanāk ārpus masīva robežām. Ja Tev šī funkcija nokaras, tad vaina varētu būt tur.

Link to comment
Share on other sites

tur vaina nebūs, masīvs ir

 

char nosaukums[51];

 

bet kaut kur vaina tomēr ir.. :)

Link to comment
Share on other sites

Baigais Janka

Nav ko muti dzesēt pa tukšo - liec iekšā programmu, ko esi uzcepis. Šitajā funkcijā, kā jau teica, kļūdas nav.

Link to comment
Share on other sites

Nav ko muti dzesēt pa tukšo - liec iekšā programmu, ko esi uzcepis. Šitajā funkcijā, kā jau teica, kļūdas nav.

 

tici man,tu nevēlēsies iedziļināties. nav no īsajām :)

 

vienīgi, man aizdomīga liekas šī funkcija. no dinamiska vienvirziena saraksta dzēš elementu pēc norādes.

 

varbūt te redzat kādas nepilnības?

 

 void delete_pt (elem *q) 
{
if (is_empty()) return;
if ((first == q) && (last == q)) 
  {
   first = last = NULL;
   delete q;
   current = NULL;
   return;
   }; 

if (first==q) 
   {current = current->next;
	delete_element();
	return;};
if (last==q) 
  {for (start(); !end(); next())
	 if (current->next==q) 
	  {last=current;
	   delete q;
	   current = NULL;  
	   return;
	   };
   return;
   };			   
start();
while (current->next!=NULL)
   {if (current->next==q){
		current->next=current->next->next;
		current = current->next;
		delete q;
		return;					
		};

   current = current->next;

   };

};

Labots - Guest
Link to comment
Share on other sites

namespace std nevaru izmantot. Varu lietot tikai stdio.h un stdlib.h bibliotēkas.

Tas tad nav C++. Tad tas ir C.

 

Varbūt ir kāda līdzīga funkcija tevis minētajai no šīm bibliotēkām?

Jā ir. memcmp.

 

Bool tipa mainīgos kompilators tāpat realizē kā int. Tur nav pilnīgi nekāda nekāda starpība.

C++'ā tas nav taisnība.

Link to comment
Share on other sites

Īsti nesaprotu, kas tas "current" tāds ir, bet Tu ļoti daudzās vietās paļaujies uz kaut kādām viņa vērtībām. Tā ir ļoti viegli nomudīties un grūti atrast kļūdas. Ieteiktu pārveidot šo funkciju tā, lai tā izmantotu tikai first, last un q. Un neizsauktu kaut kādus start() end(), u.t.t.

Link to comment
Share on other sites

Baigais Janka

Aga, nešpetni tiek operēts ar globālajiem mainīgajiem - nava labi.

Link to comment
Share on other sites

current ir tekošais saraksta elements, kurš šobrīd tiek apstrādāts. Izsaucot funkciju delete_pt(..), tai tiek padots current. varbūt klases deklarācija ieviesīs kādu skaidrību..

 

class list {
public:	  
elem *first, *last;
list () { first = last = NULL; };
elem *current;
int is_empty () { return (first == NULL); };
void start () { current = first; };
int end () { return (current == NULL); };
void next () { current = current -> next; };
void add_element (int laiksT, char darbibaT, int klientsT,char *nosaukumsT, int daudzumsT){
	elem *p = new elem (laiksT, darbibaT, klientsT, nosaukumsT, daudzumsT);
if (first == NULL) first = last = p;
else last = last -> next = p;
current=p;
};
void delete_element ()
  {elem *p = first;
first = first -> next;
delete p;//};
};

 

arī funkcija delete_pt(elem *q) ir šīs klases funkcija.

 

to bubu:

 

Manuprāt, galvenā atšķirība starp C un C++ ir tāda, C nevar izmantot klases. Man ir klases, tad jau laikam lietoju C++. Varbūt kļūdos..

Labots - Guest
Link to comment
Share on other sites

Baigais Janka

Lai dies pasargā :) Raksti tomēr vai nu C vai C++, šeit ir putra, vismaz man zuda darbaprieks iedziļināties :)

Link to comment
Share on other sites

Aga, nešpetni tiek operēts ar globālajiem mainīgajiem - nava labi.

 

kuriem?

Link to comment
Share on other sites

Baigais Janka

Nu bāc, skatos - rasktīts pēc C stila - Tev tur 90% globālie mainīgie sanāk (first, last, current etc.). Tagad pēkšņi izrādās, kas tur ir C++ klases iepītas. Vot i saku - putra :)

Link to comment
Share on other sites

first, last, current ir klases List iekšējie mainīgie.

Drošvien vajadzēja uzreiz visu klasi ar visām funkcijām iemest,tad varbūt būtu saprotamāk.. :)

Labots - Guest
Link to comment
Share on other sites

Hmm, manas domas

 

   if (first==q) 
   {current = current->next;
	delete_element();
	return;};

current teoreetiski nevajag aiztikt, ja current != first. Nezinu vai praktiski tas kaut ko var salauzt.

 

	if (last==q) 
  {for (start(); !end(); next())
	 if (current->next==q) 
	  {last=current;
	   delete q;
	   current = NULL;  
	   return;
	   };
   return;
   };

last->next netiek pieshkirts NULL, shii ir reaala probleema.

Link to comment
Share on other sites

last->next netiek pieshkirts NULL, shii ir reaala probleema.

 

Liels paldies! Šo nebiju pamanījis :)

 

par vienu soli tuvāk finišam :D

 

   if (first==q) 
   {current = current->next;
	delete_element();
	return;};

current teoreetiski nevajag aiztikt, ja current != first. Nezinu vai praktiski tas kaut ko var salauzt.

 

šinī gadījuma current == first.

 

sāku domāt,ka funkciju delete_pt () jag veidot bez argumentiem, jo kā arguments (elem*) man vienmēr tiek padots current.. un jēdzīgāk būtu to saukt delete_current() ..

Labots - Guest
Link to comment
Share on other sites

sāku domāt,ka funkciju delete_pt () jag veidot bez argumentiem, jo kā arguments (elem*) man vienmēr tiek padots current.. un jēdzīgāk būtu to saukt delete_current() ..

 

Liidziigi - delete_element() -> delete_first()

Link to comment
Share on other sites

btw funkcija delete_pt(elem*q) paradzēta šitādai lietai:

 

 

-eju ciklā cauri sarakstam

-pārbaudu vai teokošais elments nav jādzēš

-ja ir jaadzeesh-dzeeshu, bet current ir obligātu jāuzstāda uz nākošo elementu (ja ir nākošais) vai NULL(ja nupat tika izdzeest peedeejais elements), lai varētu turpināt ciklu

 

Kāds vispār ir uzdevums?

 

sarežģīts :) uzdevuma formmulējums vien ir A4 lapa. esmu pārliecināts, ak ar algoritu poroblēmas nav. tā visticamāk ir kādā no klases List metodēm.. kaut kādā brīdī programma sāk grāpstīties gar atmiņu, kas tai nepienākas :/

Labots - Guest
Link to comment
Share on other sites

Linked listi un žonglēšana ar pointeriem vienmēr ir bagātīga augsne atmiņas problēmām. Tāpēc nopietnos produktos arī dod priekšroku gataviem risinājumiem, kas ir pārbaudīti.

 

OK, Tavā gadījumā es teiktu, ka pie vainas ir tas, ka kods ir pārāk samudžināts. Derētu to sakārtot un vienkāršot. Pirmais solis - nodefinē strikti par ko ir atbildīga katra klase un katra tās funkcija. Klases funkcijām nodefinē arī, kādi ir ievaddati (tostarp globālie/klases mainīgie, kurus tās izmanto), un kādi izvaddati (arī ieskaitot izmainītos klases/globālos mainīgos). Vienmēr seko līdzi tam, lai katra klases funkcija pēc sava darba beigām klasi atstāj "kārtībā". T.i. visi klases mainīgie satur valīdus datus un nav nekādi līki pointeri palikuši pāri.

 

Pievienots: Aizmirsu pateikt - kad esi sadefinējis visu savu funkciju ievaddatus/izvaddatus, tad vari katrai funkcijai iet cauri un domāt - "vai ir kāds scenārijs, kurā viņa tomēr nedara to, ko viņai vajadzētu?" Ja ir strikti sadefinēti ievaddati/izvaddati, tad to varēs viegli izdarīt.

 

Pievienots 2: Ak, jā - un man parasti patīkt linked listi, kuri ir abos virzienos. Tad var uzreiz dabūt previous un next. Protams, divreiz vairāk pointeriem jāseko līdzi, taču, ja to visu dara uzmanīgi, tad nav tik traki. :) Parasti palīdz zīmēt kastītes ar bultiņām uz papīra, ja grūti izsekot līdzi tiem pointeriem. :)

Link to comment
Share on other sites

Pēc rotaļām ar kastītēm un bultiņām, nonācu pie secinājuma, ka arī pie algoritma vēl jāpiestrādā.. :D

Link to comment
Share on other sites

  • 2 weeks later...

Problēma atrasta :)

 

Finkcija

bool compare_string(char *a, char *b)
{
for (int i=0; i<=50;i++)
if (a[i]!=b[i]) return false;
return true;
};

 

neatzīst masīvus

 

char A [M][\n][ ][ ][ ][ ]... un

char B [M][\n][a][c][d]...

 

par vienādiem.

 

Kļūda bija tāda, ka neiztīrīju masīvu, pirms tajā rakstīju jaunas vērtības.

Labots - Guest
Link to comment
Share on other sites

nemirst

Normāli jau būtu salīdzināt virknes līdz sastop 0-to simbolu kādā no tām.

 

Nu jā, tev laikam bija domāts char masīvi. Tādā gadījuma nepiemērots nosaukums funkcijai.

Link to comment
Share on other sites

Normāli jau būtu salīdzināt virknes līdz sastop 0-to simbolu kādā no tām.

 

kaut kā tā? :)

bool compare_char_arrays(char *a, char *b)
{
for (int i=0; i<=50;i++)
  {
  if (a[i]!=b[i]) return false;
  if ((a[i]=='\n') && (b[i]=='\n') return true;
  };
return true;
};

Labots - Guest
Link to comment
Share on other sites

Tad sanāk, ka šie masīvi:

const char a[] = "ab\ncd";

const char b[] = "ab\nzyx";

ir vienādi?

 

Varbūt tomēr tavu funkciju būtu jāsauc - compare_first_line?

Link to comment
Share on other sites

Tad sanāk, ka šie masīvi:

const char a[] = "ab\ncd";

const char b[] = "ab\nzyx";

ir vienādi?

 

Būtībā mani neinteresē, kas ir aiz '\n', man šie masīvi ir vienādi :)

Prorammā šie masīvi veic tādas pašas funkcijas kā string, tāpēc ka namespace std nevaru izmantot.

Link to comment
Share on other sites

nemirst

Vispār jau C stila virknes beidzas ar 0-to simbolu, nevis newline.

Labots - nemirst
Link to comment
Share on other sites

Baigais Janka

Nu, ja Tu lieto korekti 0, kā stringa beigas, un piedevām putro C un C++ kopā - tad nemaz savu funkciju nevajag, lieto strcmp( a, b ), un miers :)

 

EDIT - Ak tā, dabojas gan inversi - atgriež 0, ja rindas vienādas.

Labots - Baigais Janka
Link to comment
Share on other sites

Izveido kontu, vai pieraksties esošajā, lai komentētu

Jums ir jābūt šī foruma biedram, lai varētu komentēt tēmas

Izveidot jaunu kontu

Piereģistrējies un izveido jaunu kontu, tas būs viegli!

Reģistrēt jaunu kontu

Pierakstīties

Jums jau ir konts? Pierakstieties tajā šeit!

Pierakstīties tagad!
 Share

×
×
  • Izveidot jaunu...