Ir para o conteúdo
Guest Markito

Alterar a ordem de apresentação dos nomes numa string

Mensagens Recomendadas

Guest Markito

Muito boa tarde; gostaria de pedir a vossa ajuda num problema de c++ que tenho que fazer.

Eu tenho que apresentar um nome em ordem inversa, ou seja se introduzir na string atravês do getline --> "Maria Antónia" ele deve retornar a string como "Antónia Maria". Este exercício vem no seguimento de outros em que tive de apresentar o mesmo (ou outro nome) na diagonal normal:

J

O

S

E

M

O

U

R

I

N

H

O.

Na diagonal contrária nome invertido:

O

H

N

I

R

U

O

M

E

S

O

J

Fiz os anteriores agora encalhei neste! Foi-me dito que podemos utilizar apenas o que aprendemos na aula: ciclo for, if, e o length().

Para o exercício imediatamente acima, fiz este código:

#include <iostream>
#include <string>
using namespace std;
int main()
{
   cout << " Introduza  um nome a sua escolha: " << endl
      << endl;
 string nome;
 getline (cin,nome);
 cout << endl;
   for(int i=nome.length()-1;i>=0;i--)
   {
       for(int j=1;j<=i;j++)
           {
               cout << " ";
           }
       cout << nome[i] << endl;
   }
   system ("pause");
   return 0;  
}

Para este ultimo exercício sei que tenho de exibir como:

#include <iostream>
#include <string>
using namespace std;
int main()
{
   cout << " Introduza  um nome a sua escolha: " << endl
      << endl;
 string nome;
 getline (cin,nome);
   for(int i=0;i<nome.length();i++)
   {
       for(int j=nome.length();j>=i;j--)
           {
               cout << " ";
           }
       cout << nome[i] << endl;
   }
   system ("pause");
   return 0;  
}

Mas tenho que trocar os nomes! Ainda fiz este porque sei que o ponto chave é o ' '(espaço), mas fiquei encalhado. Seguindo a minha linha raciocínio, conseguem ajudar-me? Quer dizer, não quero que me resolvam o problema, gostaria de pedir que me indicassem pontos chave para eu desencalhar e seguir até ao fim.

Desde já obrigado

Editado por thoga31
Correcção do GeSHi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

antes de mais, esquece o exercício antigo ... não tem nada haver ...

segundo, sem essas restrições, isso solucionava se em três tempos, mas prontos ... o que tens de fazer é (assumindo que são somente dois nomes)

- descobrir o local do espaço
- apresentar do espaço até ao final
- apresentar do início até ao espaço


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Guest Markito

Olá Hippo! Eu sou o paidacriança mas perdi a senha e agora criei este perfil! Já me ajudas-te algumas vezes antes! Obrigado!

Sim existem essas restrições eu próprio já encontrei maneiras de resolver o problema usando outras funções de strings em c++ mas o professor disse-me que tenho que usar só o que aprendemos nas aulas. Ou seja tenho que usar apenas e só: ciclos: if; for; while e trabalhar com o .length(). Aliás a beleza está em resolver o problema com a limitação de dados.

Agora estou concentrado em apresentar o nome em V. tipo:

J J

o o

s s

e e

M M

o o

u u

r r

i i

n n

h h

o

Acho que estou perto de o resolver. Logo que me concentre de novo neste já digo qualquer coisa.

Abraço Hippo!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Guest Markito

Olá Já terminei de resolver o problema do nome em V. parece que ainda era mais dificil do que o problema (que ainda está por resolver!) da inversão dos nomes! Consegui apenas com a ajuda do meu professor. Tentei demasiado e exprimentei de várias maneiras, mas com ajuda do professor ficou mais fácil. Utilizámos uma progressão matemática para dar o espaço do meio no "V", ates de imprimir o outro "braço" com a mesma string.

Vejam (obrigado professor!):

#include <iostream>
#include <string>
using namespace std;
int main()
{
   cout << " Introduza  um nome a sua escolha: " << endl
	 << endl;
   string nome;
   getline (cin,nome);

   for(int i=0, m =(nome.length()-1)*2 - 1; i < nome.length(); i++, m-=2)
    {
	    for(int j=1; j <= i; j++)
		    {
			    cout << " ";
		    }
	    cout << nome[i];
	    for(int j=1; j <= m; j++)
		    {
			    cout << " ";
		    }
	    if(i < nome.length()-1) 
		    cout << nome[i] << endl;
    }
   cout << endl;
   system ("pause");
   return 0;  
}

Agora sim, vou-me concentrar no problema deste tópico. Até já

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

Olá Já terminei de resolver o problema do nome em V.

pois ... mas ainda poderia ser simplificado.

aqui tens duas soluções (eu gosto mais da segunda ...)

#include <iostream>
#include <string>
using namespace std;

void ciclo1(string nome) {
   for(int i = 0; i < nome.length(); i++) {
       for(int j = 0; j < i; j++)
           cout << " ";
       cout << nome[i];
       if (i < nome.length() - 1) {
           for(int j = 0; j <= (nome.length() - i - 2) * 2; j++)
               cout << " ";
           cout << nome[i] << endl;
       }
   }
   cout << endl;
}

void ciclo2(string nome) {
   for (int i = 0; i < nome.length(); i++) {
       for (int j = 0; j < nome.length() * 2 - i - 1; j++) {
           if (j == i || j == nome.length() * 2 - i - 2)
               cout << nome[i];
           else
               cout << " ";
       }
       cout << endl;
   }
}

int main()
{
   cout << " Introduza  um nome a sua escolha: " << endl << endl;

   string nome;
   getline (cin, nome);

   ciclo1(nome);
   ciclo2(nome);

   return 0;
}


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Guest Markito

Sim; a 2ª tá mt elegante. O meu cérebro ainda está a entrar devagar neste meandro das matemáticas e linguagens de programação, tenha paciência sr. Hippo. E obrigado por toda a ajuda.

Até breve, vou "marrar" agora na inversão do nome. Até breve.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pikax

ja agr prefiro assim:

#include <iostream>
#include <string>
using namespace std;
void printSpace(int num)
{
   for(int i=0;i<num;i++)
    cout<<" ";
}

int main()
{
   cout << " Introduza  um nome a sua escolha: " << endl;
   string nome;
   getline(cin,nome);

   int len = nome.length();


   for(int i=0;i<len;i++)
   {
    printSpace(i);
    cout<<nome[i];
    if(i<len-1)
    {
	    printSpace((len*2)-(i*2)-3); //space between characters
	    cout<<nome[i];
    }
    cout<<endl;
   }
   cin.get();
   return 0;
}


Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

ja agr prefiro assim:

isso não é mais do que a minha primeira solução só que com separação de código de apresentar espaços numa função auxiliar ... a mim não me convençe


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pikax

e assim, retirei os ciclos desnecessarios!

#include <iostream>
#include <string>
#include <cstring>
using namespace std;

void printSpace(int num)
{
   static char* spacebuf;
   if(spacebuf==NULL)
   {
    spacebuf = new char[num];
    memset(spacebuf,' ',num);
   }
   cout.write(spacebuf,num);
}

int main()
{
   cout << " Introduza  um nome a sua escolha: " << endl;
   string nome;
   getline(cin,nome);

   int len = nome.length();
   printSpace(len*2); //so' para criar o buffer!
   cout<<endl;

   int printLastLetter = 0; // set 1 or 0

   for(int i=0;i<len;i++)
   {
    printSpace(i);
    cout<<nome[i];
    if(i<len-1 || (printLastLetter==1 && i==len-1))
    {
	    printSpace((len*2)-(i*2)-3-(-printLastLetter)); //space between characters
	    cout<<nome[i];
    }
    cout<<endl;
   }
   cin.get();
   return 0;
}


Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

e assim, retirei os ciclos desnecessarios!

http://stackoverflow.com/questions/7367677/is-memset-more-efficient-than-for-loop-in-c

Well, why don't we take a look at the generated assembly code, full optimization under VS 2010.

char x[500];
char y[500];
int i;      

memset(x, 0, sizeof(x) );   
 003A1014  push        1F4h  
 003A1019  lea         eax,[ebp-1F8h]  
 003A101F  push        0  
 003A1021  push        eax  
 003A1022  call        memset (3A1844h)  

And your loop...

char x[500];
char y[500];
int i;    

for( i = 0; i < 500; ++i )
{
   x[i] = 0;

     00E81014  push        1F4h  
     00E81019  lea         eax,[ebp-1F8h]  
     00E8101F  push        0  
     00E81021  push        eax  
     00E81022  call        memset (0E81844h)  

     /* note that this is *replacing* the loop, 
        not being called once for each iteration. */
}

So, under this compiler, the generated code is exactly the same. memset is fast, and the compiler is smart enough to know that you are doing the same thing as calling memset once anyway, so it does it for you.

If the compiler actually left the loop as-is then it would likely be slower as you can set more than one byte size block at a time (i.e., you could unroll your loop a bit at a minimum. You can assume that memset will be at least as fast as a naive implementation such as the loop. Try it under a debug build and you will notice that the loop is not replaced.

That said, it depends on what the compiler does for you. Looking at the disassembly is always a good way to know exactly what is going on.

como refere quase todas as entradas : depende do compilador.

no entanto o teu código tem algo a mais : alocação do array

no entanto, em termos de ganhos ou perdas, para o problema que é, será quase nada na mesma

no entanto, continuo a gostar mais da minha segunda solução


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pikax
no entanto o teu código tem algo a mais : alocação do array

eu poderia alocar na stack, so' que preferi nao fazer, porque teria que alocar um bom tamanho(que poderia ser pouco ou demasiado, conforme o caso).

no entanto, continuo a gostar mais da minha segunda solução

a tua solucao, tem ciclos encadeados, que eu prefiro nao usar muito.


Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

eu poderia alocar na stack, so' que preferi nao fazer, porque teria que alocar um bom tamanho(que poderia ser pouco ou demasiado, conforme o caso).

problemas, problemas ...

a tua solucao, tem ciclos encadeados, que eu prefiro nao usar muito.

gostos ... no entanto não deixa de ser uma solução mais elegante


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pikax

gostos ... no entanto não deixa de ser uma solução mais elegante

"A beleza esta nos olhos de quem a ve" :D


Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Guest Markito

Olá de novo.

Estou a começar por aqui:

#include <iostream>

using namespace std;

int main()
{
   cout << "Introduza um nome e um apelido na string: " << endl;

   string nomeApelido;
   getline(cin,nomeApelido);

   cout << nomeApelido << endl;

   system ("pause");
   return 0;    
}

Sei que a problemática deste problema reside no espaço. sei que tenho que usar um ciclo for para percorrer a string.

A minha questão é: tenho de criar 2 variáveis tipo string a partir da string inicial? Parece-me o mais lógico, pelo menos.

Obrigado desde já

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

A minha questão é: tenho de criar 2 variáveis tipo string a partir da string inicial?

não.

a única coisa que necessitas é de percorrer a mesma string duas vezes mas de forma diferente


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Guest Markito

ok, Então presumo que preciso de percorrer a string:

1º- da posição nomeApelido[o] até encontrar o ' ';

2º- e depois do nomeApelido.length()-1, em decremento até encontrar de novo o mesmo ' '.

Penso que é mais por aqui. Obrigado grande, agora não tenho tempo mas mais á noite vou "fuçar" mais um pouco. Muito obrigado amigo Hippo!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Guest Markito

Não compreendo porque é que não faz o cout dos caracteres até ao espaço.

#include <iostream>
#include <string>

using namespace std;

int main()
{
   cout << "Introduza o nome seguido do apelido: " << endl;

   string nomeApelido;
   getline(cin,nomeApelido);

   for(int i= 0; i< nomeApelido.length();i++)
       if (nomeApelido[i]==' ')
       {
           for(int j=0;j<nomeApelido[i];j++)
           cout << nomeApelido[j];
       }

   system ("pause");
   return 0; 

Se me puderem dar uma indicação. obrigado

Editado por Markito

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

o que te é apresentado ?

-----------------------------------

ps : porque estás a inventar ?

eu já te disse o que tens de fazer :

- descobrir o local do espaço
- apresentar do espaço até ao final
- apresentar do início até ao espaço

Editado por HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Guest Markito

Eu penso que não estou a inventar. Estou a tentar apresentar desde o inicio até ao espaço. depois trato do espaço até ao fim. Mas o meu esforço não está a dar resultado e nem sequer entendo porque é que não apresenta o que eu quero!

Editado por Markito

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

Eu penso que não estou a inventar. Estou a tentar apresentar desde o inicio até ao espaço. depois trato do espaço até ao fim. Mas o meu esforço não está a dar resultado e nem sequer entendo porque é que não apresenta o que eu quero!

deixa-me adivinhar ...

se escreves : "to manel maria"

o que te é apresentado é "totomanel" ... certo ?

experimenta adicinar esta linha para perceber o que está a acontecer :

   for(int i= 0; i< nomeApelido.length();i++)
       if (nomeApelido[i]==' ')
       {
           for(int j=0;j<nomeApelido[i];j++)
           cout << nomeApelido[j];
           cout << endl; // <------------
       }

Editado por HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
thoga31

Já viste bem o ciclo que criaste? Tens um ciclo que vai percorrer a string toda, e quando encontra um espaço vai percorrer de 0 até... que valor é aquele?

Para que precisas daqueles 2 ciclos? Aquilo não faz, nem perto nem longe, o que tu dizes que pretende fazer.

Faz uma coisa: comenta cada linha do teu código, explicando o que está a ser feito.


Knowledge is free! | Occasional Fortnite player

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Guest Markito

Faz uma coisa: comenta cada linha do teu código, explicando o que está a ser feito.

Acho que essa é uma boa estratégia senão ás tantas perco-me.

Obrigado ao dois. Vou fazer um reset a tudo e começar de novo com mais clareza...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.