pasar de decimal a cualquier base menor de 10

Iniciado por juanma31, 21 Mayo 2014, 20:25 PM

0 Miembros y 1 Visitante están viendo este tema.

juanma31

Holaa tengo que hacer este ejercicio y no consigo que me salga, estoy empezando con los arrays y aun no lo controlo bien:
Escriba una función que acepte de entrada una cadena y devuelva un número entero. La función efectuará la conversión de un número entero en base 10 a cualquier base menor a 10. La cadena de entrada es un string en formato "número/base". El programa principal leerá la cadena, llamará a la función, y mostrará el resultado Ejemplo: - Introduzca dato: 723/4 - Indica que el número 723 hay que convertirlo a base 4.
NOTA: Como la salida es un entero, está limitado el número de dígitos a usar. En particular, para base 2 funcionará bien para el número 1023, pero el número 1024 en base 2 requiere 11 dígitos, lo cual no cabe en la variable entera de salida, generando un resultado erróneo. Se puede evitar ese problema haciendo que la variable de salida sea de tipo cadena.

Esto es lo q yo he hecho, me salen muchos errores:

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

int Conversor(string numero,string base,string& cociente)
{
        int contador=1,i;
        cociente=numero;

        while(cociente>=base)
        {
            cociente=cociente/base;
            contador++;
        }
        for(i=contador; i>0; i--)
        {
            cociente=numero;
            contador=i;
            while(contador>1)
            {
                cociente=cociente/base;
                contador--;
            }

        }
}

int main()
{
    string numero,base;
    cout<<"Escribe el numero que quieres convertir (num/base): ";
    getline(cin,numero,'/');
    getline(cin,base,'\n');
    if(base<=10)
        Conversor(numero,base);
    else
        cout<<"Error no es una base menor de 10";
    return 0;
}



leosansan


* La librería <array> está de más.

* La función Conversor no devuelve nada por lo que debería ser de tipo void.

* Los argumentos de dicha función son los dos string, numero y base, el tercer argumento sobra.

* Tanto en la función mencionada como en main comparas y operas los string numero y base como si fueran enteros cuando previamente los has de pasar de string a int. Para ello uso la función atoi de la librería <cstdlib>, se podría hacer de otra forma pero tal vez es lo más cómodo.

Con las observaciones anteriores y respetando en lo posible tu código, a excepción de la forma que usas para cambiar de base, una posible solución sería:

Código (cpp) [Seleccionar]
#include <iostream>
#include <cstdlib>

using namespace std;

void Conversor(string numero,string base){
  int factor=1,i,resto=0,num,bas;
  num=atoi(numero.c_str()),bas=atoi(base.c_str());
  for (i=0;num>=1 ;i++ ,factor*=10){
    resto+=(num%bas)*factor;
    num=num/bas;
  }
  cout<<resto;
}

int main(){
  string  numero,base;
  cout<<"Escribe el numero que quieres convertir (num/base): ";
  getline(cin,numero,'/');
  getline(cin,base,'\n');
  if(atoi(base.c_str())<=10)
    Conversor(numero,base);
  else
    cout<<"Error no es una base menor de 10";
  return 0;
}


¡¡¡¡ Saluditos! ..... de leosansan!!!!



Blaster

Solo una observación con respecto al codigo, en el for la variable i es innecesaria puedes dejarlo simplemente asi

Código (cpp) [Seleccionar]
for(; num >= 1 ; factor *= 10, num = num/bas)
   resto += (num%bas)*factor;


Saludos

juanma31

gracias. Aunq la libreria cstdlib no la he dado y eso de atoi nunca lo he usado.
Ademas el ejercicio dice q acepte de entrada una cadena y devuelva un número entero. Y la cadena de entrada es un string en formato "número/base".
Es un ejemplo del tema de array, ¿sabrias alguna forma de hacerlo usando la libreria array?

Blaster

Cita de: juanma31 en 21 Mayo 2014, 23:05 PM
Ademas el ejercicio dice q acepte de entrada una cadena y devuelva un número entero. Y la cadena de entrada es un string en formato "número/base".

Lo que sigue ya solo son detallitos ya se te dio un codigo funcional el cual puedes adaptarlo a tus necesidades, aqui no te van hacer la tarea completita

Saludos

juanma31

tu eres la completita. Estoy aprendiendo a programar en c++ y pregunto si alguien me podria ayudar. si no quieres colaborar mantente al margen

Yoel Alejandro

Juanma, trataré de explicarte con paciencia, ya que estás comprendo que estás empezando. Necesitas la función atoi() de la biblioteca <cstdlib> para poder convertir un argumento de tipo cadena en un número entero equivalente. Pues, las operaciones aritméticas sólo tienen sentido entre argumentos que sean numéricos. Por ejemplo en el código original tenías:
Código (cpp) [Seleccionar]

cociente=cociente/base;

donde 'cociente' y 'base' son tipos string. Pero no puedes dividir dos string (!), en todo caso dividir los números representados por dichos strings, que es lo que hace atoi(): recibe una cadena y devuelve un número equivalente, e.g., el valor devuelto por la sentencia

atoi( "123" )

es el número 123, de tipo int.

A continuación voy a proponer, a modo de complemento con leosansan, una versión que da el resultado en forma de cadena y no como número decimal (lo hacemos de esta manera justo por las razones que tú expones al principio, evitar limitaciones en cuánto al número de dígitos en la salida).

Código (cpp) [Seleccionar]

#include <iostream>
#include <array>
#include <cstdlib>
#include <cstring>

using namespace std;

void Conversor( int numero, int base )
{
   int digito, i, N = 0;
   string resultado = "";
   char c;

   /* calcular la mayor potencia de la base que no supera al numero */
   while ( numero >= 1 ) {
      digito = numero % base;
      numero = numero / base;
      /* añadimos el digito, convertido a un char, al resultado */
      c = digito + '0';
      resultado = resultado + c;
      N++;
   }
   /* ahora imprimimos la cadena en reversa */
   for ( i = N - 1; i >= 0; i-- )
      cout << resultado[i];
   cout << endl;
}

int main()
{
   string str_numero, str_base;
   int numero, base;

   cout<<"Escribe el numero que quieres convertir (num/base): ";
   getline(cin, str_numero,'/');
   numero = atoi( str_numero.c_str() ); /* <-- ver aquí, convertimos el string en un entero */
   getline(cin, str_base,'\n');
   base = atoi( str_base.c_str() ); /* <-- ver aquí, convertimos el string en un entero */

   if( base <= 10 )
      Conversor( numero, base );
   else
      cout<<"Error no es una base menor de 10";

   return 0;
}


Ten en cuenta que el algoritmo de conversión que hemos usado (tanto leosansan como tú y yo) convierten el número calculando desde el dígito menos significativo hasta el más significativo, por eso la cadena debe imprimirse "al revés".

Espero te ayude.

---------------------------------------------------------------------------------------
P.D. En mi ignorancia, no conozco una función de biblioteca de C++ que imprima directamente cadenas en reversa, si alguien la sabe que me lo diga xD
Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)

Blaster

#7
Cita de: juanma31 en 21 Mayo 2014, 23:58 PM
tu eres la completita. Estoy aprendiendo a programar en c++ y pregunto si alguien me podria ayudar. si no quieres colaborar mantente al margen

juanma31 calma por que te pones en ese plan, mi unica intención era de que pusieras un poquito de esfuerzo de tu parte para solventar el resto del ejercicio

Cita de: yoel_alejandro en 22 Mayo 2014, 03:10 AM
P.D. En mi ignorancia, no conozco una función de biblioteca de C++ que imprima directamente cadenas en reversa, si alguien la sabe que me lo diga xD

yoel_alejandro puedes usar la función std::reverse de la libreria algorithm de C++

Código (cpp) [Seleccionar]
std::reverse(resultado.begin(), resultado.end());
std::cout << resultado << endl;


Saludos

eferion

Cita de: juanma31 en 21 Mayo 2014, 23:58 PM
tu eres la completita. Estoy aprendiendo a programar en c++ y pregunto si alguien me podria ayudar. si no quieres colaborar mantente al margen

Tu sigue contestando así en este foro que te vas a tener que responder tu solo a las dudas.

Ante todo educación, que somos ya mayorcitos.

¿Que estás aprendiendo? perfecto, bienvenido al mundo de la programación. Nadie dijo que fuese a ser fácil. Si te damos las cosas echas no vas a aprender absolutamente nada. Esta profesión, como cualquier otra, se aprende a base de meter la pata y de dedicarle tiempo. Además, ten en cuenta que el mundo de la programación suele ser de todo menos sencillo y fácil, vete acostumbrando a los retos porque te vas a hartar.

Así que, por favor, menos humos y más humildad. Ten en cuenta que aquí no te estamos cobrando por nuestro tiempo y nuestro conocimiento, cosa que deberías agradecer.

leosansan

Cita de: juanma31 en 21 Mayo 2014, 23:05 PM
gracias. Aunq la librería cstdlib no la he dado y eso de atoi nunca lo he usado.
Ademas el ejercicio dice q acepte de entrada una cadena y devuelva un número entero. Y la cadena de entrada es un string en formato "número/base".
Es un ejemplo del tema de array, ¿sabrías alguna forma de hacerlo usando la librería array?

Creo que confundes el usar arrays con usar la librería array.

Una posible solución sin usar atoi ni stdlib y sí arrays donde después de la entrada en el formato 123/2 tipo string paso los valores a enteros para luego poder operar con ellos:

Código (cpp) [Seleccionar]
/**
Entrada ejemplo en el formato string:123/2
**/
#include <iostream>

using namespace std;

void Conversor(int num,int bas){
  int resto=0;
  for (int factor=1;num>=1;factor*=10,num=num/bas)
    resto+=(num%bas)*factor;
  cout<<resto;
}

int main(){
  int i,lon,num=0,bas=0,factor;
  string  numero,base;
  cout<<"Escribe el numero que quieres convertir (num/base): ";
  getline(cin,numero,'/');
  getline(cin,base,'\n');
  for (lon=0;numero[lon];lon++);
  for (i=lon-1,factor=1;i>=0;i--,factor*=10)
    num+=(numero[i]-'0')*factor;
  for (lon=0;base[lon];lon++);
  for (i=lon-1,factor=1;i>=0;i--,factor*=10)
    bas+=(base[i]-'0')*factor;
  if(bas<=10)
    Conversor(num,bas);
  else
    cout<<"Error no es una base menor de 10";
  return 0;
}


¡¡¡¡ Saluditos! ..... !!!!