Jump to content
em

[C] String manipulation - Medium

Recommended Posts

Posted

S? se fac? o func?ie care înlocuie?te " " cu "spatiu" într-un string.

Restric?ie : f?r? copii ale stringului.

Spa?iu O(1). Complexitate O(n). (adic? nu ave?i voie for în for - pentru oamenii care nu au ajuns a?a departe)

Exemplu

> mama are mere

mamaspatiuarespatiumere

  • Active Members
Posted (edited)


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *rep_str(const char *s, const char *old, const char *new1)
{
char *ret;
int i, count = 0;
int newlen = strlen(new1);
int oldlen = strlen(old);

for (i = 0; s[i] != '\0'; i++)
{
if (strstr(&s[i], old) == &s[i])
{
count++;
i += oldlen - 1;
}
}
ret = (char *)malloc(i + count * (newlen - oldlen));
if (ret == NULL)
exit(EXIT_FAILURE);
i = 0;
while (*s)
{
if (strstr(s, old) == s) //compar substringul cu noul string
{
strcpy(&ret[i], new1);
i += newlen;
s += oldlen;
}
else
ret[i++] = *s++;
}
ret[i] = '\0';
return ret;
}

int main(void)
{
char mystr[100], c[10], d[10];
printf("Introdu un string:\n");
gets(mystr);
printf("Caracterul care trebuie inlocuit:\n");
scanf(" %s",c);
printf("Caracterul cu care vrem sa inlocuim:\n");
scanf(" %s",d);
char *newstr = NULL;

puts(mystr);
newstr = rep_str(mystr, c,d);
printf("%s\n", newstr);
free(newstr);
return 0;
}

//nu e compilat ca nu am avut timp. Daca e ceva wrong anunta-ma si revin cu alta solutie

//em: nu mai edita postul, f? altul

Edited by em
Posted

Salut,

Bun? solu?ia. Nu am compilat dar arat? bine.

Problema e c? strstr are un for în interior. Conform cerin?ei mele nu ai voie cu for în for :-)

E?ti aproape.

Posted (edited)

L-am scris din cap(nu garantez ca offset-urile sunt bune la string-uri):


#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

#define N 200

int main(void) {
char** s = NULL;
int i = 0;



if(!(s = (char**)malloc(2 * sizeof(char)))) {
perror("Err: ");
exit(1);
}

if(!(s[0] = (char*)malloc(N * sizeof(char)))) {
perror("Err sir: ");
exit(1);
}

if(!(s[1] = (char*)malloc(N * sizeof(char)))) {
perror("Err spatiu: ");
exit(1);
}

strncpy(s[1], "spatiu", strlen("spatiu"));
printf("Dati sirul:");
scanf("%s\n", s[0]);

for(i = 0; i < strlen(s[0]); ) {
if(s[0][i] == ' ') {
strncpy(s[0] + i + strlen(s[1]) - 1, s[0] + i + 1, strlen(s[1]) - 1);
strncpy(s[0] + i, s[1], strlen(s[1]) - 1);
i += strlen(s[1]);
} else ++i;
}

printf("Sir final: %s\n", s[0]);
free(s); free(s[0]); free(s[1]);
s = NULL;
s[0] = s[1] = NULL;
return 0;
}

In modul de mai sus aplicatie nu verifica limitele sirului. Crapa daca sirul are mai mult de 200 de caractere.

Edited by Ganav
  • Active Members
Posted
L-am scris din cap(nu garantez ca offset-urile sunt bune la string-uri):


#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

#define N 200

int main(void) {
char** s = NULL;
int i = 0;



if(!(s = (char**)malloc(2 * sizeof(char)))) {
perror("Err: ");
exit(1);
}

if(!(s[0] = (char*)malloc(N * sizeof(char)))) {
perror("Err sir: ");
exit(1);
}

if(!(s[1] = (char*)malloc(N * sizeof(char)))) {
perror("Err spatiu: ");
exit(1);
}

strncpy(s[1], "spatiu", strlen("spatiu"));
printf("Dati sirul:");
scanf("%s\n", s[0]);

for(i = 0; i < strlen(s[0]); ) {
if(s[0][i] == ' ') {
strncpy(s[0] + i + strlen(s[1]) - 1, s[0] + i + 1, strlen(s[1]) - 1);
strncpy(s[0] + i, s[1], strlen(s[1]) - 1);
i += strlen(s[1]);
} else ++i;
}

printf("Sir final: %s\n", s[0]);
free(s); free(s[0]); free(s[1]);
s = NULL;
s[0] = s[1] = NULL;
return 0;
}

In modul de mai sus aplicatie nu verifica limitele sirului. Crapa daca sirul are mai mult de 200 de caractere.

Nu ai voie sa copiezi :D -> strncpy + ca nu o sa iti afiseze tot stringul. O sa iti afiseze doar primul cuvant

Posted

Ai putea atunci lucra cu liste:


struct carac {
char c[];
carac* urm;
};

Cand intalnesti un spatiu creezi un nod carac dupa care ii modifici legaturile:


nod_curent->urm = spatiu;
spatiu->urm = nod_curent->urm->urm;
nod_curent = spatiu;

Posted
Ai putea atunci lucra cu liste:


struct carac {
char c[];
carac* urm;
};

Cand intalnesti un spatiu creezi un nod carac dupa care ii modifici legaturile:


nod_curent->urm = spatiu;
spatiu->urm = nod_curent->urm->urm;
nod_curent = spatiu;

Ideea e super. Dar hai s? ne limit?m la o func?ie cu antetul ?sta :-)

void replace(char* i_string);

Posted (edited)

#include <stdio.h>

int main()

{

char sir_initial[] = "Ana are mere!";

char sir_inlocuire[] = "_spatiu_";

char sir_nou[1024] = {0};

size_t sir_lungime = 13;

size_t sir_inloc_lungime = 8;

int pos_nou = 0;

int i = 0;

int c = 0;

while(sir_initial)

{

if(sir_initial == ' ')

{

int x = pos_nou;

pos_nou = pos_nou + sir_inloc_lungime;

while(sir_initial && sir_initial != ' ') sir_nou[pos_nou++] = sir_initial[i++];

strncpy(sir_nou + x, sir_inlocuire, sir_inloc_lungime);

i++;

}

else sir_nou[pos_nou++] = sir_initial[i++];

printf("%s\n", sir_nou);

}

return 0;

}

Edited by Nytro
  • Active Members
Posted

Done si eu. Verificat + Testat:


#include <stdio.h>
#include <string.h>
#define LUNGIME 81

void main(void){
char s1[LUNGIME],s2[LUNGIME],s3[LUNGIME],rezultat[LUNGIME];
char *s1ptr=s1,*s2pos, *rezptr=rezultat;

puts("Sirul initial:"); gets(s1);
puts("Spatiu:"); gets(s2);
puts("Cuvantul cu care inlocuim:"); gets(s3);

while(s2pos=strstr(s1ptr,s2)){
while(s1ptr<s2pos)*rezptr++=*s1ptr++;
strcpy(rezptr,s3);
rezptr+=strlen(s3);
s1ptr+=strlen(s2);
}
strcpy(rezptr,s1ptr);
puts("Sirul final:"); puts(rezultat);
}

Posted

python-ul e un fel de c mai avansat :-D

sir_initial = "Ana are mere"

sir_final = ""

for i in range(len(sir_initial)):

if sir_initial != " ":

sir_final += sir_initial

else:

sir_final += "spatiu"

print sir_final

sau:

import re

sir_initial = "Ana are mere"

print re.sub(" ", "spatiu", sir_initial)

Posted

@MrGrj :

- strstr - Parcurge sirul de caractere

- strcpy - Parcurge sirul de caractere

- strlen - Parcurge sirul de caractere

Evita strlen (specificand dimensiunea) si strstr (procesand manual sirul).

Muie em. :))

Posted (edited)

Desi am for in for algoritmul face in cazul cel mai defavorabil adica atunci cand ai numai spatii maxim 6*n+1 pasi chestie care se traduce in O(n) acum nu stiu daca iti convine pentru ca nu am facut modificarile pe acelasi vector si am folosit un vector final in care bagam string-ul nou creat.

Nu am folosit nici o functie din string.h.


#include <iostream>
using namespace std;

int main()
{

char c[1000];
cin.getline(c,1000);
char b[1000];
char s[]="spatiu";
int ct=0;
int i=0;
for( i=0;c[i]!='\0';i++)
{

if(c[i]==' ')
{
for(int j=0;j<=5;j++)
{
b[ct++]=s[j];
}
}
else
b[ct++]=c[i];
}
b[ct++]='\0';
cout<<b;
return 0;
}

Edited by parazitul29
Posted (edited)

int main(){
int i = 0, prag = 0;
char buff[10000];
const char *str1 = "mama are mere";
while (str1[i]!= '\0'){
if (str1[i] != 32) {
buff[prag++] = str1[i];
}
else
{
buff[prag] = 115;
buff[prag+1] = 112;
buff[prag+2] = 97;
buff[prag+3] = 116;
buff[prag+4] = 105;
buff[prag+5] = 117;
prag = prag + 6;
}
i++;
}
buff[prag+1] = '\0';
printf("%s\n",buff);
}

Output:


root@superstars:~/Downloads# ./rep
mamaspatiuarespatiumere

nu e f. bun codul, dar indeplineste cerintele tale :))

Edited by JIHAD
Posted (edited)

sau asa:

n-am folosit for in for.

strlen este in afara while...

int main(){
int i = 0, prag = 0;

char *replace = "spatiu";
const char *str1 = "mama are mere";
int replacelen = strlen(replace);
char buff[10000];
while (str1[i]!= '\0'){
if (str1[i] != 32) {
buff[prag++] = str1[i];
}
else
{
sprintf(buff, "%s%s",buff, replace);
prag = prag + replacelen;
}
i++;
}
buff[prag+1] = '\0';
printf("%s\n",buff);
}

Edited by JIHAD
Posted

Sper ca am inteles bine enuntul ...

Console.WriteLine("Introduceti un text");

string sir_initial = Console.ReadLine();

sir_initial = sir_initial.Replace(" ", "_spatiu_");

Console.WriteLine(sir_initial);

Console.ReadKey();

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...