How to find duplicate letter in array in C - arrays

I am making a program which requires the user to input an argument (argv[1]) where the argument is every letter of the alphabet rearranged however the user likes it. Examples of valid input is "YTNSHKVEFXRBAUQZCLWDMIPGJO" and "JTREKYAVOGDXPSNCUIZLFBMWHQ". Examples of invalid input would then be "VCHPRZGJVTLSKFBDQWAXEUYMOI" and "ABCDEFGHIJKLMNOPQRSTUYYYYY" since there are duplicates of 'V' and 'Y' in the respective examples.
What I know so far is, that you can loop through the whole argument like the following
for (int j = 0, n = strlen(argv[1]); j < n; j++)
{
//Place something in here...
}
However, I do not quite know if this would be the right way to go when looking for duplicates? Furthermore, I want the answer to be as simple as possible, right know time and cpu usage is not a priority, so "the best" algorithm is not necessarily the one I am looking for.

Try it.
#include <stdio.h>
#include <stddef.h>
int main()
{
char * input = "ABCC";
/*
*For any character, its value must be locate in 0 ~ 255, so we just
*need to check counter of corresponding index whether greater than zero.
*/
size_t ascii[256] = {0, };
char * cursor = input;
char c = '\0';
while((c=*cursor++))
{
if(ascii[c] == 0)
++ascii[c];
else
{
printf("Find %c has existed.\n", c);
break;
}
}
return 0;
}

assuming that all your letters are capital letters you can use a hash table to make this algorithm work in O(n) time complexity.
#include<stdio.h>
#include<string.h>
int main(int argc, char** argv){
int arr[50]={};
for (int j = 0, n = strlen(argv[1]); j < n; j++)
{
arr[argv[1][j]-'A']++;
}
printf("duplicate letters: ");
for(int i=0;i<'Z'-'A'+1;i++){
if(arr[i]>=2)printf("%c ",i+'A');
}
}
here we make an array arr initialized to zeros. this array will keep count of the occurrences of every letter.
and then we look for letters that appeared 2 or more times those are the duplicated letters.
Also using that same array you can check if all the letters occured at least once to check if it is a permutation

I don't know if this is the type of code that you are looking for, but here's what I did. It looks for the duplicates in the given set of strings.
#include <stdio.h>
#include <stdlib.h>
#define max 50
int main() {
char stringArg[max];
int dupliCount = 0;
printf("Enter A string: ");
scanf("%s",stringArg);
system("cls");
int length = strlen(stringArg);
for(int i=0; i<length; i++){
for(int j=i+1; j<length; j++){
if(stringArg[i] == stringArg[j]){
dupliCount +=1;
}
}
}
if(dupliCount > 0)
printf("Invalid Input");
printf("Valid Input");
}

This code snippet is used to count the duplicate letters in the array.
If you want to remove the letters, Also this code snippet is helpful .Set null when the same characters are in the same letter.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int count=0;
int array[]={'e','d','w','f','b','e'};
for(int i=0;i<array.Lenth;i++)
{
for(int j=1;j<array.Length;j++)
{
if(array[i]==array[j])
{
count++;
}
}
}
printf("The dublicate letter count is : %d",count);
}

Related

I want to print out the text with the most number of times entered

#include <stdio.h>
#include <string.h>
int main() {
char str[100];
int h[26]={0};
int i, j, count, tmp=0;
scanf("%s", str);
count=strlen(str);
for(i=0; i<count; i++) {
h[str[i]-97]++;
}
for(j=0; j<25; j++) {
if(h[j]<h[j+1]) {
tmp=j+1;
}
}
printf("%c", (char)tmp+97);
}
I want to output the most frequently entered lowercase letters, but how can I change it by output the strange values?
Try input this code "aaaabbbbsefa", then the "s" will be output.
Your code has a lot of problems. And a good bit of traps.
scanf("%s", str);
What if the input is longer than str can hold?
count=strlen(str);
This is a waste of cpu cycles. You don't need the length of a string to loop through it, you can simply check if the current element of the string is a \0
for(i=0; i<count; i++) {
h[str[i]-97]++;
}
This is problematic, what if the input contained some other character than lower case characters, this could easily cause out of bounds reading.
for(j=0; j<25; j++) {
if(h[j]<h[j+1]) {
tmp=j+1;
}
}
Firstly, this loop stops before 25, but it should stop before 26
Secondly, this definitely does not do what you think it does.
If you want to print the most frequent lower case character from in your input, this is how the flow should look like-
Take the string input and store it into a char array, make sure it can actually hold it
Declare a variable to keep track of the number of occurrences for each lowercase alphabet
Loop through the input string
Check if the current element is lowercase - if it is, add to the counter - if it isn't, do nothing
Loop through the occurrences record, check if the current occurrence is higher than the highest record (which is set to 0 before the loop) - if it higher, change the highest record to it and store the character - if it isn't, move on
Print the resulting character
This is how that'd look like in C-
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define ALPHABET_COUNT 26
#define MAX_LEN 100
int main()
{
char str[MAX_LEN];
int occurrences[ALPHABET_COUNT] = { 0 };
if (!fgets(str, MAX_LEN, stdin))
{
// Something went wrong, error handling here
return 1;
}
for (int i = 0; str[i] != '\0'; i++)
{
if (islower(str[i]))
{
occurrences[str[i] - 'a']++;
}
}
int highest_occurrence = 0;
char highest_occurring_char;
for (int i = 0; i < ALPHABET_COUNT; i++)
{
if (occurrences [i] > highest_occurrence)
{
highest_occurrence = occurrences[i];
// Convert the current index to its corresponding lowercase alphabet
highest_occurring_char = (char) (i + 'a');
}
}
printf("Highest occurring character: %c\n", highest_occurring_char);
}

Sorting strings ignoring case; uppercase first for equal strings

I have written such a piece of code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int compare_str(const void* a, const void* b)
{
char * const * aa=a;
char * const * bb=b;
return strcasecmp(*aa, *bb);
}
int sort_alphabetically(char tab[])
{
if(strlen(tab)<1 || tab[strlen(tab)-1]=='\n')
{
return 1;
}
for(unsigned int i=0; i<strlen(tab); i++)
{
if(tab[i]=='-')
{
return 1;
}
}
int spaces_count=0;
int first=0;
int ch=0;
for(unsigned int i=1; i<strlen(tab); i++)
{
if(tab[i]!=' ')
first=1;
if(tab[0]==' ' && tab[1]==' ')
ch=1;
if(tab[i]==' ' && tab[i+1]>=33 && tab[i+1]<=126 && first==1)
spaces_count++;
}
int words_count=spaces_count+1;
char **words=malloc(words_count * sizeof(char*));
char *pch;
int word_idx=0;
pch=strtok(tab, " ");
while(pch!=NULL)
{
words[word_idx++]=strdup(pch);
pch=strtok(NULL, " ");
}
qsort(words, words_count, sizeof(char*), compare_str);
for(int i=0; i<words_count; i++)
{
for(unsigned int j=0; j<strlen(words[i]); j++)
{
if(ch==0)
*(tab++)=words[i][j];
else
if(words[i][j]!=' ')
{
*(tab++)=words[i][j];
ch=0;
}
}
if(i!=words_count-1)
*(tab++)=' ';
else
*(tab++)='\0';
free(words[i]);
}
free(words);
for(unsigned int i=0; i<strlen(tab); i++)
if(tab[i]==' ' && tab[i+1]==' ')
tab[i]='\0';
return 0;
}
int main()
{
char input[1000];
printf("Enter text: ");
if(fgets(input, 1000, stdin))
{
if(input[strlen(input)-1]=='\n')
input[strlen(input)-1]='\0';
if(sort_alphabetically(input))
{
fprintf(stderr, "Incorrect input data");
return 2;
}
else
printf("%s", input);
}
return 0;
}
It sorts alphabetically words inputted by user. The thing is it makes the job but I would also like it to check if the words are the same. If they are word with first capital letter should stay before the word with first small letter.
Ex.:
Enter text:
TeChnoLOGY iS TeAChiNg Us tO Be human aGAinSiMoN MainWARing IS
Output should be:
aGAinSiMoN Be human IS iS MainWARing TeAChiNg TeChnoLOGY tO Us
But it is:
aGAinSiMoN Be human iS IS MainWARing TeAChiNg TeChnoLOGY tO Us
What changes should I make?
To achieve, what you want, you have to change your comparison function slightly.
As you observed, strcasecmp() will put the order of two equal words indeterminate. So, if strcasecmp() deems two words equal (barring the case), you have to compare them case-sensitive (with the appropriate function, you'll guess which ;) and return that result. Otherwise, just return the result of strcasecmp().
Your comparison function compare_str is a wrapper around strcasecmp(), which explicitly and specifically performs a case-insensitive comparison. If you instead want a case-sensitive comparison then exchange that for a function that provides one, or write a replacement, or just add code to compare_str to differentiate more finely in the cases where strcasecmp() returns 0, depending on exactly what ordering you want.
Since the nature and details of the question lead me to suspect that this is an academic exercise, I leave it to you to work out the details. The objective is that compare_str() must return a negative number if the first argument should be sorted before the second, a positive number if the second should be sorted before the first, or zero if either order is acceptable.

counting the number of brackets using array

I am new to coding and would really appreciate if you could help me with this question. I can't find out why my code does not give me the correct result. Thank you for your time!!
Q:
Using a first dimensional array, count the number of closing brackets and open brackets. Input must be in one line.
Ex. Input: (()))
Output: 3 2
I used an array to receive the input in one line and the for loop to count the number of opening/closing brackets.
#include <stdio.h>
int main(){
char str[1000]; int l=0;r=0;
printf("Enter:\t");
gets(str);
int length=sizeof(str)/sizeof(str[0]);
for(int i=0;i!=EOF && i<length;i++)
{
if(str[i]=='(')
l++;
else if(str[i]==')')
r++;
}
printf("%d %d",l,r);
}
Expected
Input: (())
Output: 2 2
What I get
Input: (())
Output: 6 2
i!=EOF is not needed as this is not a file
int length=sizeof(str)/sizeof(str[0]) doesnt give the length of the string strlen() from #include <string.h> does
your loop is wrong (actually your conditions)
for(size_t i = 0; i < strlen(str);i++)
{
if(str[i]=='(')
{
l++;
}
if(str[i]==')')
{
r++;
}
}
There are mistakes which are covered in basic C learning.
sizeof(str)/sizeof(str[0]); returns size of str array which is in your case 1000. To get length of user input, use strlen function: int length = strlen(str).
Later, use your for loop as for(int i=0;i<length;i++) or better:
//Include string.h on beginning of file
#include <string.h>
size_t length = strlen(str);
for (size_t i = 0; i < length; i++) {
//Do your if.
}
You also have a syntax error at the declaration of r.
You would either have int l=0,r=0;
Or
Int l=0;
Int r=0;
Although, the compiler should have warned you about this.

How to incorporate an input array in this program

This is a code that has to take an input array from the user and input the same after removing the duplicates. However, I am unsure on how to incorporate an input array in this, and right now it has the elements hardcoded. This is my first week of programming so I apologize if this is a silly question. This is the code:
#include <stdio.h>
#include <stdbool.h>
#define nelems 8
int main()
{
int l[nelems] = {1,2,3,1,4,4,5,6};
for(int m=0;m<nelems;m++)
{
bool wase = 0;
for(int n=0;n<nelems && m>n;n++)
{
if (l[m] == l[n] && m != n)
wase = 1;
}
if (wase == 0){
printf("%d\n", l[m]);
}
}
return 0;
}
Try using a for loop and scanf.
int i;
for(i=0;i<nelems;i++){
scanf("%d",&l[i]);
}
This is what you need.
#include <stdio.h>
#include <stdbool.h>
#define nelems 8
int main()
{
int i;
int l[nelems] ;
for(i=0;i<nelems;i++)
{
printf("enter %d number :",i);
scanf("%d",&l[i]);
}
for(int m=0;m<nelems;m++)
{
bool wase = 0;
for(int n=0;n<nelems && m>n;n++)
{
if (l[m] == l[n] && m != n)
wase = 1;
}
if (wase == 0){
printf("%d\n", l[m]);
}
}
return 0;
}
If you like int-type array, you can just declare another one:
int input[nelems];
and follow the user968000 advice, remembering that when you are typing the sequence in your console you have to put a white space between each number.
To avoid that, I'd rather use char-type arrays, declared as follows:
char l[nelems] = {'1', '2', '3' /*etc.*/};
char input[nelems];
Then you make a for loop, as user968000 suggested:
int i;
for(i=0;i<nelems;i++)
scanf("%c", &input[i]);
In this case you won't need the white spaces between the digits. Notice the '&' character in the scanf function: just put it as I showed, you'll surely learn what it is in next lessons.
So you have an input array and you can handle it as you want.

How can I print multiple character with one printf?

I want to print multiple character using printf. My approach up to now is this-
#include <stdio.h>
int main()
{
printf("%*c\n", 10, '#');
return 0;
}
But this only prints 9 spaces before the #.
I want to print it like this-
##########
I am unable to figure out how to do this. Please help me?
You can not use printf like that to print repetitive characters in Ansi C. I suggest you to use a loop like this -
#include <stdio.h>
int main()
{
int i;
for(i = 0; i < 10; i++) putchar('#');
return 0;
}
Or if you have absolutely no desire to use loops, you can do something like this-
#include <stdio.h>
int main()
{
char out[100];
memset(out, '#', 10);
out[10] = 0;
printf("%s", out);
return 0;
}
By the way, using printf like this also works-
#include <stdio.h>
int main()
{
printf("%.*s", 10, "############################################");
return 0;
}
I think the best approach, if you have an upper limit to the number of characters to be output is:
printf("%.*s", number_of_asterisks_to_be_printed,
"**********************************************************************");
I think this will also be the most efficient, portable way to do that.
this will print ten # characters, followed by a newline
char tenPounds[] = "##########";
printf( "%s\n", tenPounds);
I am working on a similar problem in "The C Programming Language" book (exercises 1-13 and 1-14). My own program, to start simply, is to count the occurrences of the digits 0 to 9 in a given input, and print a horizontal histogram made of '=' bars according to each count.
To do this, I created the following program;
main() {
int c, ix, k;
int nDigit[10];
//Instantiate zero values for nDigits array
for(ix = 0; ix < 10; ix++) {
nDigit[ix] = 0;
}
//Pull in input, counting digit occurrences and
//incrementing the corresponding value in the nDigit array
while ((c = getchar()) != EOF) {
if (c >= '0' && c <= '9') {
++nDigit[c-'0'];
}
}
//For each digit value in the array, print that many
//'=' symbols, then a new line when completed
for (ix = 0; ix < 10; ix++) {
k = 0;
while (k <= nDigit[ix]) {
putchar('=');
k++;
}
printf("\n");
}
}
Note that this is a work in progress. A proper histogram should include axes labels, and most importantly this program does not account for digits of zero count. If the input includes five 1's but no 0's, there is no visual way to show that we have no zeros. Still, the mechanism for printing multiple symbols works.

Resources