string do wskaźnika char *

0

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

int main()
{
char *w;
string text;
getline(cin, text);

Czy w dalszej części kodu jest możliwość zapisu stringa do chara żeby móc przy pomocy wskaźnika odczytywać litery zapisane do zmiennej text?

0

Czy ty chociaż próbowałeś użyć raz w życiu mózgu?
Podpowiem: przejrzeć dostępne metody tej klasy, użyć google, dokumentacji? C++ reference, msdn?

1

wiedz, że coś się dzieje !

0
w = text.c_str();

ale ze stringa też można przez indeks czytać poszczególne litery.

0

Dzięki @Azarien, o to mi chodziło :) Mam jednak problem z optymalnością programu
KOD 1:

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

int main()
{
    char *cstr, *p;
    char arry[2] = {1,2};
    string text;
    while(getline(cin, text))
    {
       cstr = new char[text.size()+1];
       strcpy (cstr, text.c_str());
       p = cstr;
       while(*p!=0)
       {
		     switch(*p)
             {
		           case 'X': printf("%c", 'A');
		           	break;
	               case 'Y': printf("%c", 'B');
	          		break;
		           case 'Z': printf("%c", 'C');
		           	break;
	               case ' ': printf("%c", *p++);
		           	break;
	               default: printf("%c", (char)(int)(*p++)+3);
		}
       }
       cout<<endl;
       }
       return 0;
}

KOD2:

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

int main()
{
       string text;
       while(getline(cin, text)){
       for(short i = 0; i<text.length(); i++)
       {
		switch(text[i])
		{
		case 'X': printf("%c", 'A');
			break;
		case 'Y': printf("%c", 'B');
			break;
		case 'Z': printf("%c", 'C');
			break;
		case ' ': printf("%c", (char)(int)text[i]);
			break;
		default: printf("%c", (char)(int)text[i]+3);
		}
	   }
        cout<<endl;
        }
	return 0;
}

Dlaczego KOD1 jest wolniejszy od KOD2, skoro KOD1 operuje na wskaźnikach?

0

Jest wolniejszy, bo co iterację tworzysz kopię przeczytanego stringa, zupełnie bez sensu. Wystarczy do wskaźnika p przypisać to, co zwróci metoda string::c_str.

No i tak ogólnie, wskaźniki nie są gwarantem szybkiego kodu.

p.s. nigdzie nie zwalniasz pamięci, którą przydzielasz, a to błąd.

0

a ktoś powiedział, że na wskaźnikach musi być szybciej? w pierwszej wersji kopiujesz całego stringa (strcpy) i pewnie na tym tracisz.

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

int main()
{
    const char *p;
    string text;
      while(getline(cin, text))
      {
          p = text.c_str();
          while(*p!=0)
          {
		     switch(*p)
             {
		           case 'X': printf("%c", 'A');
		           	break;
	               case 'Y': printf("%c", 'B');
	          		break;
		           case 'Z': printf("%c", 'C');
		           	break;
	               case ' ': printf("%c", *p++);
		           	break;
	               default: printf("%c", (char)(int)(*p++)+3);
		}
          }
         cout<<endl;
   }
	return 0;
}

Pomimo poprawek program dalej nie jest optymalny. Czyżby funkcja c_str() spowalniała kod?

0

Na pewno jest optymalniejszy niż był. Teoretycznie powinien być wydajniejszy niż wersja na indeksach.

Jak mierzysz czas i na jakich danych wejściowych? Zakładam, że pomiary robisz na wersji release, a nie debug.

0

Może od razu podam o jakie zadanie chodzi http://pl.spoj.pl/problems/JSZYCER/
W sumie kod na tablicach wykonuje mi się w około 0.01s natomiast ten na wskaźnikach ma przekroczony czas

0

a ja się przyczepię tego switcha:

                     switch(*p)
             {
                           case 'X': printf("%c", 'A');
                                   break;
                       case 'Y': printf("%c", 'B');
                                  break;
                           case 'Z': printf("%c", 'C');
                                   break;
                       case ' ': printf("%c", *p++);
                                   break;
                       default: printf("%c", (char)(int)(*p++)+3);
                }

czytelniej by było:

char c;
switch(*p)
{
    case 'X': c = 'A'; break;
    case 'Y': c = 'B'; break;
    case 'Z': c = 'C'; break;
    case ' ': c = *p++; break;
    default : c = (char)(int)(*p++)+3;
}
printf("%c",c);
0

Przeoczyłem to :/. Zwróć uwagę, że w momencie wystąpienia liter X, Y i Z pętla while będzie się kręcić bez przerwy, ponieważ wskaźnik p nie jest inkrementowany. Innymi słowy program się zawiesza.

p.s. nie mieszaj strumieni C ze strumieniami C++.

0

Primo:

Jedną z podstawowych metod optymalizacji jest redukcja siły operatorów. Operator [] w std::string ZTCW po prostu wywołuje operator [] na wewnętrznej tablicy, więc możemy traktować string[indeks] jako tablica[indeks].

Jeżeli mamy pętlę typu:

int s = 0;
for (int i = 0; i < N; i++) {
  s += a[i];
}

To najpierw operator [] zostanie zamieniony na operacje na wskaźnikach, czyli zamieni z pierwszej linii na drugą:

a[i]
*(a + i)

Stąd już prosta droga do optymalizacji. Po redukcji siły operatora (tzn + i, do + 1) pętla będzie wyglądać tak:

int s = 0;
int *ap = a;
for (int i = 0; i < N; i++) {
  s += *ap;
  ap++;
}

Teraz w dodatku kompilator widzi dwie inkrementacje w pętli, podczas gdy wystarczyłaby jedna. Po redukcji nadmiarowej inkrementacji zoptymalizowany kod będzie wyglądał tak:

int s = 0;
const int *apend = a + N;
for (int *ap = a; ap < apend; ap++) {
  s += *ap;
}

Secundo:
Do iterowania po stringach i wielu innych kontenerach ze stla mamy iteratory.

0

No właśnie, po co się bawić we wskaźniki, jak już Wibowit słusznie zauważył - róbmy to metodami, które zostały do tego przeznaczone.

#include <iostream>
#include <string>

int main()
{
	std::string line;

	while(std::getline(std::cin, line))
	{
		for(std::string::iterator it = line.begin(); it != line.end(); it++)
		{
			char character = *it;

			if(character >= 'A' && character < 'X')
				character = *it + 3;
			else if(character >= 'X' && character <= 'Z')
				character = *it + 2 - 'Z' + 'A';

			std::cout << character;
		}

		std::cout << std::endl;
	}

	return 0;
}
0

ja to tak zrobiłem:

#include <stdio.h>
int main()
{
  char ch;
  while ((ch=getchar())!=EOF)
    if (ch>='A' && ch<='Z')
      putchar((ch-'A'+3)%('Z'-'A'+1)+'A');
    else
      putchar(ch);
  return 0;
}

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