2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Еще одна задачка из Кернигана-Ритчи
Сообщение29.07.2012, 23:32 
Аватара пользователя
Напишите функцию htoi(s), которая преобразует строку шестнадцатеричных цифр (учитывая необязательные элементы 0х или 0Х) в ее целочисленный
эквивалент. В число допустимых цифр входят десятичные цифры от 0 до 9, а также
буквы a-f и A-F.


Я так понимаю, по условию задачи нужно написать программу перевода чисел из 16-ой с.с в 10-ую? Тогда какое решение хотели увидеть авторы? Неужели все так просто?
код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <stdio.h>
#include <conio.h>

int htoi(int a);

int main()
{
    int x;
    htoi(x);
   
    getch();
    return 0;
}

int htoi(int a)
{
    scanf("%x", &a);
    printf("%d", a);
    return a;
}

 
 
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 01:00 
Я в Сях не разбираюсь, но авторы хотели наверняка не этого. Они наверняка хотели, чтоб Вы эмулировали встроенную функцию scanf.

 
 
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 01:27 
Аватара пользователя
Dosaev писал(а):
в 10-ую?
Нет, не в десятичную. Надо перевести строку (const char *) в int, то есть в тот формат, в котором в памяти хранятся целые числа (скажем, 32-разрядные). Они ведь не в десятичной форме там хранятся.

 
 
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 17:12 
Аватара пользователя
svv в сообщении #600856 писал(а):
Нет, не в десятичную. Надо перевести строку (const char *) в int, то есть в тот формат, в котором в памяти хранятся целые числа (скажем, 32-разрядные). Они ведь не в десятичной форме там хранятся.

Не понял. В двоичные что ли? :shock:

 
 
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 17:14 
Во внутреннее представление - в виде переменной типа int, или возвращаемое значение функции типа int. А двоичное оно, или какое ещё - неважно (хотя на современных платформах - двоичное).

 
 
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 17:48 
Аватара пользователя
То есть массив перевести в переменную типа int?

 
 
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 18:52 
Аватара пользователя
Да. Строка — это массив символов. Её нужно перевести в переменную типа int.

 
 
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 19:41 
Аватара пользователя
Вот немного состряпал. Это недоработка, она даже не работает по той причине, что pow возвращает float-ское значение. Как мне преобразовать значение dec? Или вообще я не то делаю? И как быть с буквами a b c d e f?
код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <stdio.h>
#include <conio.h>
#include <string.h>

#define MAXLINE 1024

void getline(char str[], int lim);
int htoi(char str[]);

int main()
{
    char str[MAXLINE];
    getline(str, MAXLINE);
    printf("%d", htoi(str));

    getch();
    return 0;
}
/* старая функция для ввода массива */
void getline(char str[], int lim)
{
    int c, i;
   
    for(i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
          str[i] = c;
         
    if (c == '\n')
       str[i] = c;
   
    ++i;
    str[i] = '\0';
}
/* вот искомая функция */
int htoi(char str[])
{
    int dec = 0;
   
    int length = strlen(str);
    length--;
   
    int i;
    for(i = 1; i <= length; ++i) {
          /* switch (str[i-1])
          {
                 case 'a': str[i-1] = ; // вот тут как быть, если символ одна из букв?
                 case 'b': str[i-1] = ;
                 case 'c': str[i-1] = ;
                 case 'd': str[i-1] = ;
                 case 'e': str[i-1] = ;
                 case 'f': str[i-1] = ;
          } */

          str[i-1] -= '0';
          dec += str[i-1]*pow(16, length - i);
    }
   
    return dec;
}

 
 
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 21:17 
Интересно, что код символа '0' Вы догадались вычесть, а код символа 'a' $\text{---}$ нет. Ведь буквы (обычно) идут в таблице символов тоже по порядку (алфавитному). Впрочем, даже если бы это и было не так, Ваш вариант с использованием конструкции switch ... case вполне адекватен (только не стоит забывать про слово break). Что же касается возвращаемого функцией pow значения, то его, конечно, можно было бы преобразовать к целочисленному, используя приведение типов или какую-нибудь функцию математической библиотеки (округление, взятие целой части и т.п.), однако в данном случае гораздо лучше эту функцию и вовсе не использовать, а лишь заметить, что $\overline{a_n a_{n-1}\ldots a_2 a_1 a_0}=10\cdot \overline{a_n a_{n-1}\ldots a_2 a_1}+a_0$.
P.S. К нумерации с 0 еще не привыкли?

 
 
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение31.07.2012, 09:14 
Аватара пользователя
EtCetera в сообщении #601229 писал(а):
заметить, что $\overline{a_n a_{n-1}\ldots a_2 a_1 a_0}=10\cdot \overline{a_n a_{n-1}\ldots a_2 a_1}+a_0$.


Так все равно же придется 10ку возводить в степень, т.е использовать функцию pow для представления числа $\overline{a_na_{n-1}...a_1a_0} = a_n \cdot 10^n + a_{n-1} \cdot 10^{n-1} + ... + a_1 \cdot 10 + a_0.$ Нет?

-- Вт июл 31, 2012 09:21:05 --

EtCetera в сообщении #601229 писал(а):
P.S. К нумерации с 0 еще не привыкли?

Может быть не привык, но в данной программе удобно с 1 по-моему, там все равно 0-ой элемент используется.

 
 
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение31.07.2012, 09:33 
Аватара пользователя
Код:
M = 0;
for(i=0; str[i]!='\0'; i++) {
  c = str[i];
  if (c=='x' || c=='X' && M==0) continue;
  if (c>='0' || c<='9') c -= '0';
  else if ('a' <= c && c<='f') c = 10 + c - 'a';
  else if ('A' <= c && c<='F') c = 10 + c - 'A';
  else break;
  M = M*16 + c;
}

Как-то так

 
 
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение31.07.2012, 09:40 
Аватара пользователя
Хм, лаконично. :|
Спасибо.

-- Вт июл 31, 2012 10:39:26 --

Day, странно, но выдает всегда 0. :-( В чем причина? Никак не могу понять...
код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <stdio.h>
#include <conio.h>

#define MAXLINE 1000

void getline(char s[], int lim);
int htoi(char s[]);

int main()
{
  char chislo[MAXLINE];
 
  getline(chislo, MAXLINE);
  printf("%d", htoi(chislo));
 
  getch();
  return 0;
}

/* íó ýòî ñòàðàÿ ãåòëàéíîâñêàÿ ôóíêöèÿ äëÿ ââîäà ìàññèâà */
void getline(char s[], int lim)
{
    int c, i;
   
    for(i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
          s[i] = c;
         
    if (c == '\n')
       s[i] = c;
   
    ++i;
    s[i] = '\0';
}

int htoi(char s[])
{
     int c, M, i;
     
     M = 0;
     
     for(i = 0; i != '\0'; i++) {
           c = s[i];
         if(c == 'x' || c == 'X' && c == '0') continue;
         if(c >= '1' && c <= '9') c -= '0';
         else if(c >= 'a' && c <= 'f') c = 10 + c -'a';
         else if(c >= 'A' && c <= 'F') c = 10 + c - 'A';
         else break;
         M = M*16 + c;
     }    
    return M;
}

 
 
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение31.07.2012, 10:52 
Смущает строка
Код:
if(c == 'x' || c == 'X' && c == '0') continue;

А именно: "&&". с не может равняться 2 одновременно разным значениям.
И цикл for написан неверно, т.к. он не выполнит ни одной итерации. Ибо 0 ='\0'. Он в него даже не зайдет ни разу.
Замените цикл на while. Чтоб итератором был указатель на текущий символ. Тогда вы сможете обработать последовательность "0x". И не забудьте про то, что 0 тоже число, а не только встречается в последовательности "0x".

 
 
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение31.07.2012, 14:48 
Аватара пользователя
Ух! Вроде все работает. Спасибо всем за помощь. :wink:
код: [ скачать ] [ спрятать ]
Используется синтаксис C
int htoi(char s[])
{
     int c, M, i;
     
     M = 0;
     
     for(i = 0; s[i] != '\0'; i++) {
         if(s[i] == '0') {
              ++i;
              if (s[i] == 'x' || s[i] == 'X') ++i;
         }
         c = s[i];
         if(c >= '1' && c <= '9') c -= '0';
         else if(c >= 'a' && c <= 'f') c = 10 + c -'a';
         else if(c >= 'A' && c <= 'F') c = 10 + c - 'A';
         else break;
         M = M*16 + c;
     }    
    return M;
}

 
 
 [ Сообщений: 14 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group