#finding isogram

19 messages · Page 1 of 1 (latest)

exotic mountain
#

by isogram i mean a unique occurencce of a character, to not be repeated twice either upper or lowercased

#include <stdio.h>
#include <stdbool.h>

int main(){
    
    int j=0;
    unsigned short alphabet_poz[52][2];
    char phrase[]="hey there";
    unsigned short phrase_len,alphabet_poz_len;

    // here at first i thought that the uniqueness also concerns the UpperCase & LowerCase but it's not 
    // meaning that A==a 
    for (char alpha='A'; alpha<='Z'; alpha++) {
        alphabet_poz[j][0]=alpha;
        alphabet_poz[j][1]=0;
        j++;
    }
    for (char alpha='a'; alpha<='z'; alpha++) {
        alphabet_poz[j][0]=alpha;
        alphabet_poz[j][1]=0;
        j++;
    }

    phrase_len=sizeof(phrase);
    alphabet_poz_len=sizeof(alphabet_poz)/sizeof(alphabet_poz[0]);
    
    // here it gets quiet messy so bare with me 
    for (int index=0; index<phrase_len; index=index+1) {
        // iterating over each character in the phrase
        for (int iterv0=0; iterv0<=alphabet_poz_len/2; iterv0++) { 
            // here i divided by 2 the alpha_poz len cause it's 52 i only wanted the first 26, and i'm adding 26 later on to find it's lowercase alt 
            int iterv1=iterv0+26; // here
            // i'm iterating over the alphabets to check whether the char is matching or not
            if ((alphabet_poz[iterv0][1]==1 && phrase[index]==alphabet_poz[iterv0][0]) || (alphabet_poz[iterv1][1]==1 && phrase[index]==alphabet_poz[iterv1][0])) {
                // iterv0 will go the range of Upper while iterv1 will go in the range of lower
                
                return printf("it's not an isogram");
            }
            if ((phrase[index]==alphabet_poz[iterv0][0])||(phrase[index]==alphabet_poz[iterv1][0])) {
                alphabet_poz[iterv1][1]++; // adding to occurence of both upper and lower
                alphabet_poz[iterv1][0]++;
            }
        }
    }
    return printf("it's an isogram");
}
errant berryBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

midnight monolith
#

you may be overthinking this a bit. you basically want to walk through your phrase and see if any letters are duplicated while treating upper and lower case as if they are the same, correct?

#

presumably all non-alphabetic characters including space would be treated as unique characters, yes? There is a library function that will convert letters to upper or lower case while leaving other characters unchanged.

#

why not keep an array of flags representing each unique character, using that character as an index into the array. if the flag is set you have seen the character before and are therefore done and don't have an isogram. If you get to the end without duplicates, you have an isogram.

jade drift
# exotic mountain by isogram i mean a unique occurencce of a character, to not be repeated twice e...

as an alternative to the above suggestion of keeping some look-up table:

sort your string (because it's just a consecutive array of char, after all...) and once that is done, finding whether it's an isogram or not is trivial; something like :

unsigned char *the_string; // use `unsigned char` so the comparator can be `a-b`
qsort(...);

for(unsigned char c;(c = *(the_string++));) {
  if(*the_string == c) return 0;
}
return 1; // isogram

I suspect this approach is more memory dmanding than the look-up table above when your string is bigger than letters of your alphabet

exotic mountain
#

i get segmentation fault when i test against NULL

i updated the code, here it is

#include "isogram.h"
#include <stdio.h>
#include <string.h>

bool is_isogram(char phrase[]){
    
    int j=0;
    unsigned short alphabet_poz[52][2];
    unsigned short phrase_len,alphabet_poz_len;

    for (char alpha='A'; alpha<='Z'; alpha++) {
        alphabet_poz[j][0]=alpha;
        alphabet_poz[j][1]=0;
        j++;
    }
    for (char alpha='a'; alpha<='z'; alpha++) {
        alphabet_poz[j][0]=alpha;
        alphabet_poz[j][1]=0;
        j++;
    }

    phrase_len=strlen(phrase);
    alphabet_poz_len=(sizeof(alphabet_poz)/sizeof(alphabet_poz[0]))/2;

    for (int idx=0; idx<=phrase_len; idx++) {
        for (int iterv0=0 ; iterv0<alphabet_poz_len ; iterv0++) {
            int iterv1=iterv0+26;
            //printf("how true :%d\n", (alphabet_poz[iterv0][0]==phrase[idx]) || (alphabet_poz[iterv1][0]==phrase[idx]));
            if ((alphabet_poz[iterv0][1]==1 || alphabet_poz[iterv1][1]==1) && (phrase[idx]==alphabet_poz[iterv0][0] || phrase[idx]==alphabet_poz[iterv1][0])) {
                printf("it's not an isogram");
                return false;
            }
            if ((alphabet_poz[iterv0][0]==phrase[idx]) || (alphabet_poz[iterv1][0]==phrase[idx])) {
                alphabet_poz[iterv1][1]++;
                alphabet_poz[iterv0][1]++;
                continue;
            }

            //printf("\nalpha_poz[iterv0][1]==1 : %d\t alpha_poz[iterv1][1]==1 : %d\n",alphabet_poz[iterv0][1]==1,alphabet_poz[iterv1][1]==1);

        }
    }
    printf("it's an isogram");
    return true;
}
#

i was told that char var[] is the syntatic sugar of char *var so they're the same, but the first one wasn't allowing me to assign null to it while the second results in a segmentation fault

#

how to debug a segmentation fault

i tried printing stuff even before initialization and still doesn't work

jade drift
#

phrase_len=strlen(phrase);

#

how to debug a segmentation fault

assert more; prove you can do what you're doing by reading the spec; use a sanitizer; use a debugger; grab a coffee

midnight monolith
# exotic mountain how to debug a segmentation fault i tried printing stuff even before initializa...

Build your code with the -g command line option and run it in the debugger. For example:

$ gdb -q a.out
Reading symbols from a.out...
(gdb) run
Starting program: a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
No command line argument provided.

Program received signal SIGSEGV, Segmentation fault.
__strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:74
74    ../sysdeps/x86_64/multiarch/strlen-avx2.S: No such file or directory.
(gdb) bt
#0  __strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:74
#1  0x000055555555526d in is_isogram (phrase=0x0) at testfoo.c:25
#2  0x00005555555554a2 in main (argc=1, argv=0x7fffffffe5b8) at testfoo.c:58
(gdb) 

Notice that the parameter passed to is_isogram is NULL. Any dereference of that pointer is going to seg fault such as was done by trying to pass it to strlen(). Simply check the phrase parameter passed to is_isogram for NULL and return false will cure your seg fault.

jade drift
#

sometimes there is no real need for those tools: proper assertions and care when coding is very valuable. but learning how to use a debugger is definitely important 👍

exotic mountain
exotic mountain
# midnight monolith Build your code with the -g command line option and run it in the debugger. For...

yeah i also struggle with the pointer thing, i know i started coding in c but i still think i code more like javascript or python, you can see here in this code:

#include <stdio.h>
#include <stdbool.h>
#include <string.h>

int main(){
    
    int j=0;
    unsigned short alphabet_poz[52][2];
    char *phrase=NULL;
    unsigned short phrase_len,alphabet_poz_len;

    if (phrase==NULL) {
        return printf("it's not an isogram");
    }

    for (char alpha='A'; alpha<='Z'; alpha++) {
        alphabet_poz[j][0]=alpha;
        alphabet_poz[j][1]=0;
        j++;
    }
    for (char alpha='a'; alpha<='z'; alpha++) {
        alphabet_poz[j][0]=alpha;
        alphabet_poz[j][1]=0;
        j++;
    }
    
    phrase_len=strlen(phrase);
    alphabet_poz_len=(sizeof(alphabet_poz)/sizeof(alphabet_poz[0]))/2;

    printf("the length of NULL is %d",phrase_len);

    for (int idx=0; idx<=phrase_len; idx++) {
        for (int iterv0=0 ; iterv0<alphabet_poz_len ; iterv0++) {
            int iterv1=iterv0+26;
            //printf("how true :%d\n", (alphabet_poz[iterv0][0]==phrase[idx]) || (alphabet_poz[iterv1][0]==phrase[idx]));
            if ((alphabet_poz[iterv0][1]==1 || alphabet_poz[iterv1][1]==1) && (phrase[idx]==alphabet_poz[iterv0][0] || phrase[idx]==alphabet_poz[iterv1][0])) {
                return printf("it's not an isogram");
            }
            if ((alphabet_poz[iterv0][0]==phrase[idx]) || (alphabet_poz[iterv1][0]==phrase[idx])) {
                alphabet_poz[iterv1][1]++;
                alphabet_poz[iterv0][1]++;
                continue;
            }

            //printf("\nalpha_poz[iterv0][1]==1 : %d\t alpha_poz[iterv1][1]==1 : %d\n",alphabet_poz[iterv0][1]==1,alphabet_poz[iterv1][1]==1);

        }
    }
    printf("it's an isogram");
}
#

i just learned about the bit when it comes to format specifiers like the c is 1 byte and int is 4 byte

royal wasp
exotic mountain
royal wasp