unix Posted November 14, 2024 at 05:39 PM Report #633683 Posted November 14, 2024 at 05:39 PM boa tarde companheiros, estou tentando criar um jogo, onde o user passa uma string e o programa embaralha elas e o jogador tenta acertar. mas meu problema é que não sei como embaralhar as strings #include <stdio.h> #include <string.h> #include <stdlib.h> int main(){ int len = 0; char *str = (char *) malloc(sizeof(char) * 4096); if(str == NULL){ realloc(str, sizeof(char) * 1024); } char *copy = (char *) malloc(sizeof(char) * 4096); if(copy == NULL){ realloc(copy, sizeof(char) * 1024); } printf("Str: "); fgets(str, (sizeof(char) * 4096), stdin); char *token = strtok(str, ";"); while(token != NULL){ // junta as strings e aumenta 1 strcat(copy, token); len = len +1; token = strtok(NULL, ";"); } // diminui 1 len--; printf("string: %s\n", copy); free(str); free(copy); return 0; } "Viva o hoje e aproveite o amanhã." autor esquecido
antseq Posted November 15, 2024 at 09:27 AM Report #633685 Posted November 15, 2024 at 09:27 AM Em 14/11/2024 às 17:39, unix disse: boa tarde companheiros, estou tentando criar um jogo, onde o user passa uma string e o programa embaralha elas e o jogador tenta acertar. mas meu problema é que não sei como embaralhar as strings viva, já programei muito em c, c++, mas há anos que não tenho oportunidades de trabalhar nisto. do que vejo no teu código (posso estar errado): 1. fazes "malloc" de 4096, caso não seja possível, tentas fazer "realloc" de apenas 1024 >> salvo erro, tens de assignar o "str = realloc(…" 2. fazes um "fgets" com size 4096 fixo independentemente de acima teres conseguido 4096 ou apenas 1024 >> para não complicar, nesta fase, usa sempre 1024, 256, 126 em todos (as tantas 80 seria suficiente) 3. dizes que o user passa uma string e o programa deve embaralhar… a seguir usas "strtok" para partir a string delimitada por ";" >> o teu código está a pegar nisto str="a;b;c;d;e;f" e a transformar nisto copy="abcdef" É isto que pretendes? >> o user envia "uma" string com várias strings separadas por ";", tipo "não sei como;criar um jogo;boa tarde" >> queres separar e baralhar esta lista de strings ["não sei como", "criar um jogo", "boa tarde"] ? >> o user deve acertar em que? Ou apenas? >> o user envia UMA string com VÁRIOS caracteres, sem separadores, tipo "portugal" >> baralhas os caracteres "logtprua" >> o user tenta acertar em "logtprua" ? 1 Report
thoga31 Posted November 23, 2024 at 04:26 AM Report #633735 Posted November 23, 2024 at 04:26 AM Vou partir do princípio que queres baralhar os caracteres de uma string. Caso queiras baralhar um conjunto de strings separados por ;, o que vou falar pode ser um bom princípio, mas necessitará de mais trabalho em cima. A fim de baralhar a string podes usar a própria string original para ir mantendo registo dos caracteres que já usaste e de quais faltam baralhar. Tendo uma string com N caracteres, executas um ciclo N vezes com um contador i que vai de 0 a N - 1: Obter uma posição pseudo-aleatória P no intervalo [0, N - i); Copiar para a posição i da string baralhada o caracter na posição P da string original; Trocar, na string original, os caracters das posições P e N - i - 1. Ao executar acontece algo deste género: Insert string: abcdef i = 0 | pos = 4 | original = "abcdfe" | shuffled = "e" i = 1 | pos = 1 | original = "afcdbe" | shuffled = "eb" i = 2 | pos = 3 | original = "afcdbe" | shuffled = "ebd" i = 3 | pos = 1 | original = "acfdbe" | shuffled = "ebdf" i = 4 | pos = 1 | original = "acfdbe" | shuffled = "ebdfc" i = 5 | pos = 0 | original = "acfdbe" | shuffled = "ebdfca" original = "abcdef" shuffled = "ebdfca" Na primeira iteração (i = 0) gerei o número pseudo-aleatório 4 (intervalo [0, 6)) peguei no caracter original[4], e, coloquei em shuffled[0] e depois troquei os caracteres original[4] e original[5]. A string original ficou passou de abcdef para abcdfe e a shuffled ficou com o primeiro caracter. Desta forma ficou no último caracter da original aquele que já "baralhámos", pelo que só podemos pegar numa posição pseudo-aleatória no intervalo [0, 5) na iteração seguinte. O processo repete-se, e como pegámos no caracter b, repararás que passámos de abcdfe para afcdbe. Desta forma garantimos sempre que os caracteres baralhados já não serão reutilizados, usando sempre o mesmo espaço de memória. Em código: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define MAXLEN 256 // Comenta se não quiseres mostrar o progresso no ciclo "for" #define DEBUG /* Aloca uma string de tamanho "len", colocando todos os bytes a "zero" */ static inline char *make_str(size_t len) { return (char*)calloc(len, sizeof(char)); } /* Aloca memória com uma cópia da string de origem */ char *make_copy(const char *src, size_t len) { char *copy = make_str(len); if (copy) strncpy(copy, src, len); return copy; } /* Obtém string do utilizador e remove "new line" se estiver presente no final */ size_t get_string(const char *prompt, char *str, const size_t maxlen) { printf("%s", prompt); fgets(str, maxlen, stdin); size_t len = strlen(str); if (str[len - 1] == '\n') str[--len] = '\0'; return len; } /* Obtém um número pseudo-aleatório no intervalo [min, max) (i.e. exclusive "max") */ static inline int get_rand_int(int min, int max) { return min + rand() % (max - min); } int main(void) { // Aloca memória para string original e obtém o input do utilizador char *original = make_str(MAXLEN); if (!original) return 1; size_t len = get_string("Insert string: ", original, MAXLEN); // Cópia da original, apenas porque vou mostrar a string original no final mas vou precisar de a modificar char *copy_original = make_copy(original, len + 1); if (!copy_original) { free(original); return 2; } // Aloca memória para a string baralhada char *shuffled = make_str(len + 1); if (!shuffled) { free(original); free(copy_original); return 3; } // Inicializa variáveis temporárias e "randomizador" int pos = 0; char temp = '\0'; srand(time(NULL)); // Vamos baralhar! for (size_t i = 0; i < len; ++i) { pos = get_rand_int(0, len - i); shuffled[i] = temp = original[pos]; original[pos] = original[len - i - 1]; original[len - i - 1] = temp; #ifdef DEBUG printf("i = %3lu | pos = %3d | original = \"%s\" | shuffled = \"%s\"\n", i, pos, original, shuffled); #endif } printf("original = \"%s\"\nshuffled = \"%s\"\n", copy_original, shuffled); free(original); free(copy_original); free(shuffled); return 0; } O output de exemplo supra-citado foi gerado com uma execução deste código. Cumprimentos. Knowledge is free!
HappyHippyHippo Posted December 2, 2024 at 10:46 AM Report #633756 Posted December 2, 2024 at 10:46 AM @unix : percebo que quando uma pessoa tem uma dúvida, seja difícil a explanar. pois se não fosse dúvida, as coisas eram simples. peço só para tentar ser um pouco mais claro na próxima vez, eu acredito que consigas porque já vi perguntas bem mais difíceis de compreender aqui. @thoga31 eu gosto de código um pouco mais simples 😄 #include <stdlib.h> #include <stdio.h> #include <string.h> #define MAXLEN 256 int main() { size_t len = MAXLEN; char *original = NULL, *shuffled = NULL; // aloca memória para string original if ((original = (char*) calloc(len, sizeof(char))) == NULL) return 1; // pedir a string ao utilizador do { len = 0; printf("Insert string: "); if (fgets(original, MAXLEN, stdin) != NULL) { len = strlen(original); if (original[len - 1] == '\n') original[--len] = '\0'; } } while (len == 0); // criar o resultado com base na original if ((shuffled = (char*) malloc(len + 1)) == NULL) { free(original); return 1; } strncpy(shuffled, original, len + 1); // baralhar a string gerada for (size_t i = 0; i < len; i++) { size_t pos = i + rand() % (len - i); if (pos != i) { char aux = shuffled[i]; shuffled[i] = shuffled[pos]; shuffled[pos] = aux; } } // apresentar as strings printf("%s|%s\n", original, shuffled); // libertar a memória alocada free(original); free(shuffled); return 0; } IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now