Я учусь C и, чтобы сделать его более интересным, я использую Codingame: веб-сайт, где вы должны решать задачи с помощью кода. Есть такая головоломка, которая называется «Чак Норрис», где вы получаете массив символов и вам необходимо выдать определенный результат, используя одну функцию printf (). Например, символ 'C' представлен как 1000011 в двоичном виде. 1 представлен одним '0', за которым следует пробел и число 0, соответствующее числу 1. Итак:
1 -> 0 0
11 ->0 00
111 ->0 000
Если двоичный файл равен 0, он будет работать так же, но будет быть представленным двойным 0.
0 -> 00 0
00 -> 00 00
000 ->00 000
Таким образом, для символа C (1000011) результат будет "0 0 00 0000 0 00".
- ввод состоит из символов ASCII (7-разрядных).
- Если вы получили строку, вам не нужно добавлять пробелы между конечным 0 и первым нулем второго символа. Так что «CC» будет «0 0 00 0000 0 000 0 00 0000 0 00».
- '/ n' не рассматривается.
Итак, я решил это но, похоже, я не очень хорошо это сделал: код отнимает слишком много времени, а веб-сайт говорит, что я мог бы его жестко закодировать. Ниже вы найдете мой мыслительный процесс и мой код.
Мыслительный процесс
Чтобы преобразовать строку в двоичный файл, мне понадобится цикл, который проходит по каждому символу и делит значение int 2 проверяя напоминание. После этого я должен сохранить его в массиве, в 7 раз превышающем strlen указанной строки. Теперь у меня есть массив со всеми символами, которые хранятся в двоичном виде: мне просто нужно go через массив в обратном порядке и посчитать количество 0 или 1 с в строке. Если a имеет n 0 в строке, мне просто нужно объединить переменную, добавив «00», «0» n раз и пробел. То же самое для 1с подряд. Итак, вот мой код:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/**
* Auto-generated code below aims at helping you parse
* the standard input according to the problem statement.
**/
int main()
{
char MESSAGE[101], bits[strlen(MESSAGE)*7]; // Message is the variable in input given by the
website. Bits is my variable to store message in binary.
fgets(MESSAGE, 101, stdin);
char *pointer = MESSAGE;
char result[256] = ""; // variable used to store the result
int i=0;
int count = 0;
int numberc, countz, countone; /* numberc servers to represent the number of characters in the
string(Excluded /n). countz counts the number of 0s in a row and countone counts the number of 1s in
a row */
countz = 0;
countone = 0;
numberc = strlen(MESSAGE) - 1 ;
for(i=0; i<=strlen(MESSAGE); i++)
{
bits[i] =0;
}
while(*pointer != '\n'){ //cycle that goes through every char of the string until it encounters '\n'
int temp=*pointer;
for(int j=0; j<7; j++){ // cycle the selected char into binary and stores it in the var 'bits'
if(temp % 2 == 1)
bits[count] = '1';
else
bits[count] = '0';
temp = temp/2;
count++;
}
pointer++;
}
numberc = numberc * 7;
for(int j=numberc-1; j>=0; j--){ // cycle that goes through all the bits stored in reverse
if(bits[j] == '0'){
countz++; // counting zeros in a row
if(countone != 0){ // concatenating the string in case the previous bits were 1s in a row and the current one is 0
strcat(result, "0 ");
for(i=0; i<countone; i++){
strcat(result, "0");
if (i == (countone -1)) strcat(result, " "); //adding the space after concatenation
}
countone = 0;
}
}
else if(bits[j] == '1'){
countone++; // counting ones in a row
if(countz != 0){ // concatenating the string in case the previous bits were 0s in a row and the current one is 1
strcat(result, "00 ");
for(i=0; i<countz; i++){
strcat(result, "0");
if (i == (countz -1)) strcat(result, " "); //adding the space after concatenation
}
countz = 0;
}
}
// since the cycle above does not take into account the last row of 1s or 0s, i just repeat the process once again checking the counters and avoiding adding a space at the end.
}
if(countone != 0){
strcat(result, "0 ");
for(i=0; i<countone; i++){
strcat(result, "0");
if (i == (countone -1)) strcat(result, " ");
}
countone = 0;
}
if(countz != 0){
strcat(result, "00 ");
for(i=0; i<countz; i++){
strcat(result, "0");
if (i == (countz -1)) strcat(result, " ");
}
countz = 0;
}
printf("%s", result);
return 0;
}
Итак, мой вопрос: что я могу сделать лучше? Как я могу упростить мой код? Есть ли какая-то функция, которую я не знаю, которая может помочь мне в этом случае? Я признал, что часть моего кода плохая. Например:
- объявление результата var неверно, так как я дал фиксированное число массивов символов. Хотя я и думал об этом, я не знаю, как программно дать измерение массива, которое имеет смысл.
- Часть кода избыточна.
- Управление памятью отсутствует (у меня есть пока не изучал)
Код отлично работает с одним или двумя символами ASCII, но когда я ставлю 3+ или пробел, он начинает выдавать странные выходные данные.
Извините для длинного поста я пытался объяснить себя как можно более четко. Кроме того, пожалуйста, будьте терпеливы, поскольку я новичок ie до C, а английский sh не мой родной язык.