How do you validate that a vector can not repeat letters in c ++?

2

I have been trying to make a validation that when entering letters in a vector does not allow repetitions of the letters, for example I enter the letter "a" and I re-enter it should appear to me that it has already been entered but I can not do it ... This is the code I have, I hope someone can help me!

#include "stdafx.h"
#include "iostream"
#include "stdio.h"

using namespace std;

void noRepetir();

int main()
{
    int opc = 0;
    do {
        noRepetir();
        cout << "Ingresar otro dato? (1 = Si | 0 = No) ";
        cin >> opc;
    } while (opc == 1);

    return 0;
}

void noRepetir() {

    char vector[20];
    char letra;

    cout << "Ingrese la letra: ";
    cin >> letra;
    for (int i = 0; i < 20; i++) {

        if (letra != vector[i]) {
            vector[i] = letra;
        }
        else {
            cout << "Esta letra ya ha sido ingrasada " << endl;
        }
    }
} 
    
asked by user73355 25.01.2018 в 03:17
source

3 answers

2

Let's focus on the centerpiece of your algorithm:

cout << "Ingrese la letra: ";
cin >> letra;
for (int i = 0; i < 20; i++) {

    if (letra != vector[i]) {
        vector[i] = letra;
    }
    else {
        cout << "Esta letra ya ha sido ingrasada " << endl;
    }
}

1st mistake

Imagine that it is the first letter that is entered ... the algorithm will compare it with the 20 positions that the array has ... And what is there in those positions of the array? since you have not initialized it, trash ... so one possibility could be:

df!f20y43%_SD435?a.{

Notice that in the last positions there is a a :

df!f20y43%_SD435?a.{
                 ^

So the algorithm will tell you that the letter is repeated even though it is the first letter that is entered ...

The solution to this problem is as simple as initializing vector before entering a word:

std::fill(vector,vector+20,'0');

Or you can also initialize the vector when declaring it:

char vector[TamVector] = {'
const int TamVector = 20;
char vector[TamVector];

// ...

for( int i=0; i<TamVector; i++ )
// ...
'};

Although I personally do not really like having that 20 swarming through the code ... if then I have to change the size of the array I have to look for that 20 throughout the code to avoid errors. It would be better to have something like this:

const int TamVector = 20;

int main()
{
  char vector[TamVector] = {'
if (letra != vector[i]) {
    vector[i] = letra; // <<---
}
'}; noRepetir(vector, TamVector); } void noRepetir(char *vector, int tamVector) { // ... }

2nd mistake

  

and I re-enter it should appear to me that it has already been entered but I can not do it ...

If you notice, you will see that vector is a local variable of noRepetir . What noRepetir does is read a single letter and look for it in vector , after which it returns control to main . When this happens the content of vector is lost, since the variable is destroyed ... Since the idea is that the array is somewhat more persistent maybe you should declare it in main :

aaaaaaaaaaaaaaaaaaaa

This will ensure that the information you store in vector is persistent between calls to noRepetir ... but the program will still not work ...

... and the reason is the line that I highlight:

xxxxxxxxxxxxxxxxxxxx

Why is that line problematic?

Let's see ... the user enters a letter and the algorithm compares it with the 20 positions of vector . If the letter is not equal to the one stored in the vector ... it overwrites the letter stored in the vector with the letter that the user has entered.

That is, if we assume that you initialize vector and that it is the first letter that the user enters, after calling noRepetir the vector will remain this way (suppose the user enters a ):

int i; // Ahora es necesario que 'i' esté fuera del bucle
bool unica = true;

// Primero comprobamos que la letra no se ha introducido aun
for( i=0; i<tamVector && vector[i] != '
#include <iostream>

void noRepetir(char * vector, int tamVector);

int main()
{
  int const TamVector = 20;
  char vector[TamVector] = {'
cout << "Ingrese la letra: ";
cin >> letra;
for (int i = 0; i < 20; i++) {

    if (letra != vector[i]) {
        vector[i] = letra;
    }
    else {
        cout << "Esta letra ya ha sido ingrasada " << endl;
    }
}
'}; int opc = 0; do { noRepetir(vector,TamVector); std::cout << "Ingresar otro dato? (1 = Si | 0 = No) "; std::cin >> opc; } while (opc == 1); return EXIT_SUCCESS; } void noRepetir(char * vector, int tamVector) { char letra; std::cout << "Ingrese la letra: "; std::cin >> letra; int i; bool unica = true; for( i=0; i<tamVector && vector[i] != '
df!f20y43%_SD435?a.{
' && unica; i++ ) unica = (vector[i] != letra); if( unica ) { if( i < tamVector ) vector[i] = letra; } else { std::cout << "Esta letra ya ha sido ingrasada\n"; } }
' && unica; i++ ) unica = (vector[i] == letra); // Y despues, si no esta repetida, la añadimos al array if( unica ) { if( i < tamVector ) // Importante para no escribir fuera del array vector[i] = letra; // antes de esta linea vector[i]=='
df!f20y43%_SD435?a.{
                 ^
' } else { std::cout << "Esta letra ya ha sido ingrasada\n"; }

If you then enter a x :

std::fill(vector,vector+20,'0');

Seen the seen it does not seem a good idea that the algorithm crushes vector positions so lightly.

What you have to do is modify the loop so that it iterates from 0 until it finds a position of the uninitialized vector vector[i]=='vector' and, if the letter entered by the user is not found in %code% , add it only in the first available position. Something like this:

char vector[TamVector] = {'
const int TamVector = 20;
char vector[TamVector];

// ...

for( int i=0; i<TamVector; i++ )
// ...
'};

The program, with the corresponding corrections:

const int TamVector = 20;

int main()
{
  char vector[TamVector] = {'
if (letra != vector[i]) {
    vector[i] = letra; // <<---
}
'}; noRepetir(vector, TamVector); } void noRepetir(char *vector, int tamVector) { // ... }
    
answered by 25.01.2018 в 08:31
2

Apart from the excellent response from eferion , I wanted to suggest the use of C ++ STL libraries for your code, specifically the headers <string> and <algorithm> .

Your char vector[20]; can be replaced by a std::string and your entire function noRepetir can be a call to std::count . So your code would be, simply:

int opc = 0;
std::string letras;

do {
    int letra;
    std::cout << "Ingrese la letra: ";
    std::cin >> letra;

    if (std::count(letras.begin(), letras.end(), letra))
        std::cout << "Esta letra ya ha sido ingrasada\n";
    else
        letras.push_back(letra);

    std::cout << "Ingresar otro dato? (1 = Si | 0 = No) ";
    std::cin >> opc;
    std::cout << letras << '\n';

} while (opc == 1);

The std::count function counts how many times the third parameter appears between the past iterators as first and second parameters; therefore if it returns something other than 0 it will mean that the letra ya ha sido ingresada .

When using a std::string instead of a training 1 you should not worry about controlling the position in which to write as you can accumulate data by std::string::push_back .

1 Or array, also known as array in English.

    
answered by 25.01.2018 в 11:35
1

This works:

#include "iostream"
#include "stdio.h"

using namespace std;

// noRepetir() ya toma dos argumentos, el vector donde guardo las letras y el numero de letras que llevo agregadas
int noRepetir(char arg_vector[], int arg_cont_letras);

int main()
{
    int opc = 0;
    char my_vector[20];
    // cont_letras cuenta el numero de letras que llevo
    // en el vector para saber en que indice agregarla
    int cont_letras = 0;
    do {
        // mi funcion noRepetir devuelve 0 en caso de que la letra este repetida
        // aca verifico si la letra se agrego para aumentar el numero de letras agregadas (cont_letras)
        if (noRepetir(my_vector, cont_letras) != 0){
            cont_letras++;
        }
        cout << "Ingresar otro dato? (1 = Si | 0 = No) ";
        cin >> opc;
    } while (opc == 1);

    return 0;
}

int noRepetir(char arg_vector[], int arg_cont_letras) {
    char letra;

    cout << "Ingrese la letra: ";
    cin >> letra;
    // itero en el vector verificando si la letra ya fue almacenada
    for (int i = 0; i < arg_cont_letras; i++) {

        if (letra != arg_vector[i]) {
            continue;
        }
        // si la letra ya esta almacenada devuelvo 0
        else {
            cout << "Esta letra ya ha sido ingrasada " << endl;
            return 0;
        }
    }
    // si el flujo de mi programa llego hasta aca quiere decir que la letra no esta almaceenada en el vector
    // almaceno la letra, aca entra el papel de saber cuantas letras llevo almacenadas para poder almacenarla
    // en ese indice del vector
    arg_vector[arg_cont_letras] = letra;
}

I edit for the appreciation of @paula_plus_plus

#include "iostream"
#include "stdio.h"

using namespace std;

// noRepetir() ya toma dos argumentos, el vector donde guardo las letras y el numero de letras que llevo agregadas
int noRepetir(char arg_vector[], int arg_cont_letras);

int main()
{
    int opc = 0;
    // inicializo el vector como buena practica, sin embargo
    // esto no afecta el funcionamiento del algoritmo
    char my_vector[20] = {'
#include "iostream"
#include "stdio.h"

using namespace std;

// noRepetir() ya toma dos argumentos, el vector donde guardo las letras y el numero de letras que llevo agregadas
int noRepetir(char arg_vector[], int arg_cont_letras);

int main()
{
    int opc = 0;
    char my_vector[20];
    // cont_letras cuenta el numero de letras que llevo
    // en el vector para saber en que indice agregarla
    int cont_letras = 0;
    do {
        // mi funcion noRepetir devuelve 0 en caso de que la letra este repetida
        // aca verifico si la letra se agrego para aumentar el numero de letras agregadas (cont_letras)
        if (noRepetir(my_vector, cont_letras) != 0){
            cont_letras++;
        }
        cout << "Ingresar otro dato? (1 = Si | 0 = No) ";
        cin >> opc;
    } while (opc == 1);

    return 0;
}

int noRepetir(char arg_vector[], int arg_cont_letras) {
    char letra;

    cout << "Ingrese la letra: ";
    cin >> letra;
    // itero en el vector verificando si la letra ya fue almacenada
    for (int i = 0; i < arg_cont_letras; i++) {

        if (letra != arg_vector[i]) {
            continue;
        }
        // si la letra ya esta almacenada devuelvo 0
        else {
            cout << "Esta letra ya ha sido ingrasada " << endl;
            return 0;
        }
    }
    // si el flujo de mi programa llego hasta aca quiere decir que la letra no esta almaceenada en el vector
    // almaceno la letra, aca entra el papel de saber cuantas letras llevo almacenadas para poder almacenarla
    // en ese indice del vector
    arg_vector[arg_cont_letras] = letra;
}
'}; // cont_letras cuenta el numero de letras que llevo // en el vector para saber en que indice agregarla int cont_letras = 0; do { // mi funcion noRepetir devuelve 0 en caso de que la letra este repetida // aca verifico si la letra se agrego para aumentar el numero de letras agregadas (cont_letras) if (noRepetir(my_vector, cont_letras) != 0){ cont_letras++; } cout << "Ingresar otro dato? (1 = Si | 0 = No) "; cin >> opc; } while (opc == 1); return 0; } int noRepetir(char arg_vector[], int arg_cont_letras) { char letra; cout << "Ingrese la letra: "; cin >> letra; // itero en el vector verificando si la letra ya fue almacenada for (int i = 0; i < arg_cont_letras; i++) { if (letra != arg_vector[i]) { continue; } // si la letra ya esta almacenada devuelvo 0 else { cout << "Esta letra ya ha sido ingrasada " << endl; return 0; } } // si el flujo de mi programa llego hasta aca quiere decir que la letra no esta almaceenada en el vector // almaceno la letra, aca entra el papel de saber cuantas letras llevo almacenadas para poder almacenarla // en ese indice del vector arg_vector[arg_cont_letras] = letra; }
    
answered by 25.01.2018 в 03:33