How to find whether the string is a Lapindrome? [closed] - c

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
The following code is giving correct output as given on the codechef problem page: http://www.codechef.com/problems/LAPIN
but getting wrong answer on submission
please tell me the possible problem with my code
here is the question
Lapindrome is defined as a string which when split in the middle, gives two halves having the same characters and same frequency of each character. If there are odd number of characters in the string, we ignore the middle character and check for lapindrome. For example gaga is a lapindrome, since the two halves ga and ga have the same characters with same frequency. Also, abccab, rotor and xyzxy are a few examples of lapindromes. Note that abbaab is NOT a lapindrome. The two halves contain the same characters but their frequencies do not match.
Your task is simple. Given a string, you need to tell if it is a lapindrome.
Input:
First line of input contains a single integer T, the number of test cases.
Each test is a single line containing a string S composed of only lowercase English alphabet.
Output:
For each test case, output on a separate line: "YES" if the string is a lapindrome and "NO" if it is not.
and here is the code
#include<stdio.h>
#include<string.h>
int main()
{
int f,t,mid,len;
char arr[1000];
int left[125],right[125];
scanf("%d",&t);
for(int i=0;i<t;i++)
{
f=0;
scanf("%s",arr);
memset(left,0,sizeof(left));
memset(right,0,sizeof(right));
len=strlen(arr);
for(int i=0;i<len/2;i++)
left[arr[i]]++;
for(int i=(len+1)/2;i<len;i++)
right[arr[i]]++;
for(int i=0;i<strlen(arr);i++)
{
if(left[arr[i]]!=right[arr[i]])
f++;
break;
}
if(f==0)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}

I recommend you read up on modularity; it'll make your life easier.
#include <stdio.h>
#define BOOL unsigned char
#define TRUE 1
#define FALSE 0
unsigned string_length(char *string)
{
unsigned counter = 0;
while (string[counter++] != '\0') { }
return counter - 1;
}
BOOL are_equal(unsigned *a, unsigned *b, int size)
{
int i;
for (i = 0; i < size; ++i)
{
if (a[i] != b[i])
{
return FALSE;
}
}
return TRUE;
}
BOOL is_lapindrome(char *string)
{
unsigned left[26] = { 0 }, right[26] = { 0 },
str_len = string_length(string);
if (str_len < 2)
{
return FALSE;
}
int i;
for (i = 0; i <= str_len / 2 - 1; ++i)
{
left[string[i] - 'a']++;
}
for (i = (str_len + 1) / 2; i < str_len; ++i)
{
right[string[i] - 'a']++;
}
return are_equal(left, right, 26);
}
int main()
{
char *list[6] =
{
"gaga",
"abcde",
"rotor",
"xyzxy",
"abbaab",
"ababc"
};
int i;
for (i = 0; i < 6; ++i)
{
printf("%s\n", is_lapindrome(list[i]) == TRUE ? "YES" : "NO");
}
return 0;
}

Your buffer is one byte too short - a string of 1000 characters requires 1001 chars, the last one taken by the nul terminator.
"lowercase English alphabet" sounds a bit ambiguous - I'd say that by some interpretation, it could contain spaces. If so, the input will be read incorrectly.
I can't see other problems right now, but I'd strongly suspect the first one.

Related

remove duplicates in a string with a buffer [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I’m trying to remove duplicates in a string using a map. Running it through GDB I'm not able to figure out where the code is failing, though the logic to me seems right.
Could anyone please point out the mistake?
int main() {
char *str="I had my morning tea";
int len = strlen(str);
int dupArr[256] = {0};
//Build the map
int i=0;
for(i;i<256;i++)
dupArr[str[i]]++;
//If the count is 1 then print that value.
i=0;
for(i;i<256;i++) {
if(dupArr[str[i]] == 1) {
printf("%c\n",str[i]);
}
}
}
output
I h y o r i g t % c 4 # } ` 8 � F J
I get up to 't' ,which is correct but then i see magic chars.
Your string has length of len but you are traversing till 256 which is out of bound.
Use len when inserting into the hash.
int i=0;
for(i;i<LEN;i++)
dupArr[str[i]]++;
Also if your are checking the duplicates then it should be bigger than 1 since your are ++ the first encountered char
if(dupArr[str[i]] > 1)
In addition to Mark Ezberg's good answer, note that dupArr[str[i]]++; poses a problem when str[i] < 0.
Better to treat the characters as unsigned char:
int dupArr[UCHAR_MAX + 1] = {0};
....
dupArr[(unsigned char) str[i]]++;
Rolling this and other ideas together:
int main(void) {
char *str="I had my morning tea";
size_t dupArr[UCHAR_MAX + 1] = {0};
unsigned char *s = (unsigned char *) str;
while (*s) {
dupArr[*s]++;
s++;
}
for(unsigned i = 0; i <= UCHAR_MAX; i++) {
// A duplicate is when dupArr[i] is _more_ than 1.
if(dupArr[i] > 1) {
printf("%c\n",str[i]);
}
}
}

what does "not all control paths return a value” mean in this program? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I wrote a code that takes inputs until an EOF integer (999999 in this case) is typed. Then it sorts the numbers and searches for our needle (an integer) in that array of integers (called haystack). Now I am facing a problem in my searching algorithm. While compiling it shows me a warning:
'search': not all control paths return a value
I think it means that the function might not return anything in some cases but the problem is that i can't think of any such case. I even checked my program with a lot of values and it always gave me the correct output. Can anyone help me figure out where the problem lies. I was use some windows native tools compiler for this.
Also if anyone has seen the CS50 pset3 find problem which is related to this, I used the same search function there too but while compiling the code in CS50 IDE the program never showed whether it found the needle in haystack. It only arranged them in increasing order and then stopped after that.
#include <stdio.h>
#include "cs50.h"
#include <stdlib.h>
bool search(int value, int values[], int n);
void sort(int values[], int n);
// maximum amount of hay
#define MAX 65536
int main(int argc, string argv[])
{
// ensure proper usage
if (argc != 2)
{
printf("Usage: ./find needle\n");
return -1;
}
// remember needle
int needle = atoi(argv[1]);
// fill haystack
int size;
int haystack[MAX];
for (size = 0; size < MAX; size++)
{
// wait for hay until EOF
printf("\nhaystack[%i] = ", size);
int straw = GetInt();
if (straw == 999999)
{
break;
}
// add hay to stack
haystack[size] = straw;
}
printf("\n");
// sort the haystack
sort(haystack, size);
// try to find needle in haystack
if (search(needle, haystack, size))
{
printf("\nFound needle in haystack!\n\n");
return 0;
}
else
{
printf("\nDidn't find needle in haystack.\n\n");
return 1;
}
}
/**
* Returns true if value is in array of n values, else false.
*/
bool search(int value, int values[], int n)
{
/* TODO: implement a searching algorithm */
int first = 0;
int last = n;
int middle = (first + last) / 2;
while (first + 1 < last)
{
if (value == values[middle])
{
return true;
break;
}
if (value == values[first])
{
return true;
break;
}
if (value == values[last])
{
return true;
break;
}
if (value < values[middle])
{
last = middle;
middle = (first + last) / 2;
}
if (value > values[middle])
{
first = middle;
middle = (first + last) / 2;
}
}
if (first + 1 >= last)
{
return false;
}
}
/**
* Sorts array of n values.
*/
void sort(int values[], int n)
{
// TODO: implement an O(n^2) sorting algorithm
for (int j = 1; j < n; j++)
{
for (int i = 0; i < (n - 1); i++)
{
if( values[i + 1] < values[i])
{
int b = values[i + 1];
values[i + 1] = values[i];
values[i] = b;
}
}
}
for (int k = 0; k < n; k++)
{
printf("haystack[%d] = %d ", k, values[k]);
}
}
The compiler does not execute your code. It does not do value tracking. While you can reason about the values of variables and expressions, this is generally an unsolvable problem for the compiler.
Your compiler tells you that it doesn't know what to return from search when control reaches the function's closing }.
BTW, it is a bad idea to write a function named sort, since the C Standard Library contains a function with the same name.

Problems with creating a function to reverse a string [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 7 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I need to create a fuction that returns a string. So far I have come up with this code:
#include <stdio.h>
#include <string.h>
#define SIZE 256
void str_reverse(char[SIZE], char[SIZE]);
int main(void)
{
char input[SIZE];
char output[SIZE];
printf("Please enter a string\n");
fgets(input, SIZE, stdin);
str_reverse(input, output);
printf("%s \n", output);
return 0;
}
void str_reverse(char in[SIZE], char out[SIZE])
{
int i = strlen(in);
int k = 0;
for(int j = i; j>= 0; j--)
{
out[k] = in[j];
k++;
}
}
However, whenever I try to run the code, I do not get an output. Does anyone have any idea what could be wrong
The problem is this line
int i = strlen(in);
Change it to
int i = strlen(in)-1;
strlen() returns the size of the string, hence when you start copying from in[], in[j] would be \0. which is getting stored in out[0].
Another change you need to do is put a \0 in the out[], just after the for loop
for(int j = i; j>= 0; j--)
{
out[k] = in[j];
k++;
}
out[k] = '\0';
Your "reversing" includes the null character too. So the reversed string's first character is '\0'. So the string is empty.
Change:
for(int j = i ; j>= 0; j--)
to
for(int j = i - 1; j>= 0; j--)
You should also check if the string length is zero before the for loop. Otherwise, i-1 will become SIZE_MAX and you'll have problems with that!
A simple condition such as the following in str_reverse() would handle that case:
size_t i = strlen(in);
int k = 0;
if (i<=1) return; //empty string or contains only 1 char char.
i starts out at strlen(in), so the first character you copy over tooutis the null byte at the end of the string. Every other character then appears after the null terminator, soout` is an empty string.
Start with i at strlen(in) - 1, then add the null terminator and the end of the loop:
int i = strlen(in) - 1; // start at the last non-null character
int k = 0;
for(int j = i; j>= 0; j--)
{
out[k] = in[j];
k++;
}
out[k] = '\0'; // add the null terminator
When k is 0 and j is i, you do the following:
out[0] = '\0';
Hence, out looks like an empty string when the function returns.
Use:
for(int j = i-1; j>= 0; j--)
{
out[k] = in[j];
k++;
}
out[k] = '\0';
In the function variable i is set the following way
int i = strlen(in);
So within the loop
for(int j = i; j>= 0; j--)
{
out[k] = in[j];
k++;
}
then j is equal to i then in[j] is equal to the terminating zero '\0' of string in. Thus array out starts from zero that is it will contain an empty string.
It is better to declare the function itself the following way
char * str_reverse( char *out, const char *in );
and to return from the function the pointer out. In this case you could write for example
puts( str_reverse( output, input ) );
Take into acount that function fgets usually also stores the new line character in the string. You should remove it. you can do it the following way
input[strcspn( input, "\n" )] = '\0';
Also instead of the type int in this statement
int i = strlen(in);
it is better to use type size_t.
size_t i = strlen(in);
It is the type of the return value of the function strlen. But in this case you should also to write the loop correctly.:)

C programming: ouput two strings as two columns next to each other

I have a question regarding an issue with a program in C I am making. I am going to write two different strings next to each other in two columns. I haven't found clear answers to my question since they almost always give examples of numbers with a known length or amount.
I have two strings, with a maximum length of 1500 characters, but to me unknown length. Let's for the sake of learning given them these values:
char string1[] = "The independent country is not only self-governed nation with own authorities.";
char string2[] = "This status needs the international diplomatic recognition of sovereignty.";
I want to write them next to each other, with a column width of twenty characters. I have set the difference between the columns to a regular 'tab'. Like this:
The independent coun This status needs th
try is not only self e international dipl
-governed nation wit omatic recognition o
h own authorities. f sovereignty.
I have tried with the following code but it isn't effective since I can't figure out how to adapt it to the length of the strings. It also just adapted to write five rows. I also get the below error.
Could someone please give me an example of how this could be done, and maybe with a pre-defined c-function in order to avoid using the for-loops.
void display_columns(char *string1, char *string2);
int main()
{
char string1[] = "The independent country is not only self-governed nation with own authorities.";
char string2[] = "This status needs the international diplomatic recognition of sovereignty.";
display_columns(string1,string2);
}
void display_columns(char *string1, char *string2)
{
int i,j;
for(i=0;i<5;i++)
{
for(j=0+20*i;j<20+20*i;j++)
{
printf("%c",string1[j]);
}
printf("\t");
for(j=0+20*i;j<20+20*i;j++)
{
printf("%c",string2[j]);
}
}
}
I guess this is more generic way to do it.
void print_line(char *str, int *counter) {
for (int i = 0; i < 20; i++) {
if (str[*counter] != '\0') {
printf("%c", str[*counter]);
*counter += 1;
}
else { printf(" "); }
}
}
void display_columns(char *string1, char *string2)
{
int counter = 0, counter2 = 0;
while (1) {
print_line(string1, &counter);
printf("\t");
print_line(string2, &counter2);
printf("\n");
if (string1[counter] == '\0' && string2[counter2] == '\0') {
break;
}
}
}
To print a single character, use:
printf("%c",string1[j]);
or
putchar(string1[j]);
This is the reason for the warnings and segmentation fault.
With this fix, the program somewhat works, you just have to print a newline as the last part of the loop:
for(i=0;i<5;i++)
{
for(j=0+20*i;j<20+20*i;j++)
{
putchar(string1[j]);
}
printf("\t");
for(j=0+20*i;j<20+20*i;j++)
{
putchar(string2[j]);
}
putchar('\n');
}
Update: For the function to work with strings of variable lengths, try this:
void display_columns(char *string1, char *string2)
{
int i,j;
int len1 = strlen(string1);
int len2 = strlen(string2);
int maxlen = (len1 > len2) ? len1 : len2;
int numloops = (maxlen + 20 - 1) / 20;
for(i=0; i<numloops; i++)
{
for(j=0+20*i;j<20+20*i;j++)
{
if (j < len1)
putchar(string1[j]);
else
putchar(' '); // Fill with spaces for correct alignment
}
printf("\t");
for(j=0+20*i;j<20+20*i;j++)
{
if (j < len2)
putchar(string2[j]);
else
break; // Just exit from the loop for the right side
}
putchar('\n');
}
}

Caesar Cipher Algorith Shifting C [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
So I was writing a C program to make use of caesar algorithm using a custom table, where I will give the table and shifting will be done using that table e.g the text "abc" according to table "abc" with key=1 should be ciphered as bca, however i am having difficulty on the last characters if key+index of letter is higher than the length of the table stored here is my code
void encrypt (char table[],char entext[],char text[],int key)
{
int i,j;
int k = strlen(table);
//int result = (key + k);
for (i=0;i<strlen(table);++i)
{
j = 0;
if (text[i]!='\0')
{
while (text[i]!=table[j])
{
j++;
}
if ((j+key)>k)
{
j=(j+key)%k;
//j = (result - j);
}
else
j = j + key;
entext[i] = table[j];
}
}
entext[i+1] = '\0';
puts(entext);
}
int main()
{
char table[100] , text[100] , entext[100] , c;
int i , j , key;
printf("Enter the text : ");
gets(text);
printf("Enter the table : ");
gets(table);
printf("Enter the key : ");
scanf("%d",&key);
encrypt(table,entext,text,key);
system("pause");
return 0;
}
if ((j+key)>k)
should be
if ((j+key)>=k)
Besides, this check is completely unnecessary because of how mod works. I will take the liberty to rewrite your code so it looks nicer:
void encrypt (char table[],char entext[],char text[],int key)
{
int i,j;
int k = strlen(table);
//int result = (key + k);
for (i=0;i<strlen(table);++i)
{
if (text[i]!='\0')
{
for(j=0; text[i] != table[j] ;j++);
entext[i] = table[(j+key)%k];
}
}
entext[i+1] = '\0';
puts(entext);
}
I believe you could make this "table" lookup more efficient by indexing the value of the char itself, but unless you are dealing with pretty big input, this won't really make a difference.
void encrypt (char table[], char entext[], char text[], int key) {
int i,j;
int k = strlen(table);
for (i=0;text[i];++i){
for(j=0;table[j] && text[i]!=table[j];++j)
;
if(table[j]=='\0')//character not find at table
entext[i] = text[i];//Not slide. // or Error?
else {
j += key;
if(j>=k)
j -= k;//j = j % k
entext[i] = table[j];
}
}
entext[i] = '\0';
puts(entext);
}

Resources