My code is supposed to compare 2 strings and returns the common characters in alphabetical order. If there are no common chars, it will return a null string.
However the program is not running.
Code
void strIntersect(char *str1, char *str2, char *str3)
{
int i,j, k;
i = 0;
j = 0;
k = 0;
while(str1[i]!='\0' || str2[j]!='\0')
{
if(strcmp(str1[i],str2[j])>0)
{
str3[k] = str1[i];
k++;
}
else if (strcmp(str2[j],str1[i])>0)
{
str3[k] = str2[j];
k++;
}
i++;
j++;
}
}
Example
Input string 1:abcde
Input string 2:dec
Output: cde
How do I get it to work?
There are quite a few problems with your code
strcmp is not needed for a simple char comparison
Is the 3rd char string allocated by the caller?
Your approach won't work if source strings are either of different sizes or are not alphabetical.
My solution assumes that input is ASCII, and is efficient (used a simple char array with indexes denoting ASCII value of the character).
If a character is found in str1, the char map will have a 1, if it is common, it will have a 2, otherwise, it will have a 0.
void strIntersect(char *str1, char *str2, char *str3)
{
int i=0, j=0, k=0;
char commonCharsMap[128] = { 0 };
while(str1[i] != '\0')
{
commonCharsMap[str1[i++]] = 1;
}
while(str2[j] != '\0')
{
if(commonCharsMap[str2[j]] == 1)
{
commonCharsMap[str2[j++]] = 2;
}
}
for(i=0; i<128; i++)
{
if(commonCharsMap[i] == 2)
{
str3[k++] = i;
}
}
str3[k++] = '\0';
}
int main()
{
char str1[] = "abcde";
char str2[] = "dce";
char str3[30];
strIntersect(str1, str2, str3);
printf("Common chars: %s\n", str3);
return 0;
}
A option is to iterate over the complete second string for each character in the first string
int i = 0;
int k = 0;
while(str1[i] != '\0') {
int j = 0;
while(str2[j] != '\0') {
if (str1[i] == str2[j]) {
str3[k] = str1[i];
k++;
}
j++;
}
i++;
}
I replaced the strcmp because you are comparing single characters not a string
Your if case and Else if case are identical and you are just comparing elements according to your Index. i.e you are comparing first element with first, second with second and so on. This won't provide you solution. I suggest use two for loops. I will provide you code later if you want
Related
I'm learning C recently and I didn't learn about pointers so still not allowed to use it.
Note: i'm not allowed to use it or any function from string.h library.
I wrote a function that removes the "\n" from a string.
when I run my program appears to me:
main.c:20:14: warning: comparison between pointer and integer
main.c:80:39: warning: format not a string literal and no format arguments [-Wformat-security]
This is my function:
#include <stdio.h>
#define STRING_SIZE 100
void replace(char str[]){
int i=0;
while(str[i]!='\0'){
if(str[i]=="\n"){
str[i]='\0';
}
}
}
int my_strlen(char s[]) {
int i = 0;
while (s[i] != '\0') {
i++;
}
return i;
}
int remover(char s1[], char s2[], char s3[]) //removes the sustring s2 from string s1 and saved it to s3
{
int i = 0, j, t = 0, found;
while (s1[i])
{
found = 1;//Initilize found to true
for (j = 0; s2[j] != 0; j++) {
if (s1[i + j] != s2[j])
found = 0;//Set not found
}
if (found == 0) {
s3[t] = s1[i];// if not found add char to s3.
t++;
}
else {
i = i + my_strlen(s2) - 1;//if found skip
}
i++;
}
s3[t] = 0;
if (my_strlen(s1) > my_strlen(s3)) {
return 1;
}
return 0;
}
int main() {
char result_string[STRING_SIZE+1], MainString[STRING_SIZE+1], PatternString[STRING_SIZE+1];
printf("Please enter the main string..\n");
fgets(MainString, STRING_SIZE + 1, stdin);
replace(MainString);
printf("Please enter the pattern string to find..\n");
fgets(PatternString, STRING_SIZE + 1, stdin);
replace(PatternString);
int is_stripped = remover(MainString, PatternString, result_string);
printf("> ");
printf(is_stripped ? result_string : "Cannot find the pattern in the string!");
return 0;
}
what's the problem?
You have a lot of problems:
Your function returns a char, which is a single character.
A C-style string has to have a terminating zero byte. You don't put one on helper. So even if you could return it properly, the code that got it would have no way to know how long the string was.
You allocate helper on the stack in replace, so helper stops existing when you return. So where will the returned string be stored?
Just remove the '\n' from the string, in place, modifying the original string.
For instance:
void remove_newline(char str[])
{
int i;
for(i=0; str[i] != 0; ++i)
{
if (str[i] == '\n')
{
str[i] = 0;
break;
}
}
}
I was asked this question in an interview but I was not able to answer.
Question was: To remove a specific characters from a given string by traversing string only once.
e.g. Given string is: "aaabbcdabe"
remove all 'b'
output: ""aaacdae"
I made this logic but it was traversing string more than once:
for(int i=0; str[i]!='\0'; i++)
{
if(str[i] == 'b')
{
for(j=i; str[j]!='\0'; j++)
{
str[j] = str[j+1];
}
}
}
With this logic, string is getting traversed more than once, once in outer for loop and many times in shifting operation.
Is there any other way to do this?
Keep a pointer to the read location and a pointer to the write location. Each time the read-pointer is advanced, only write through the write-pointer if the character is not being removed. Advance the write-pointer only when a character is written:
#include <stdio.h>
void remove_chars(char *str, const char c);
int main(void)
{
char test_str[] = "aaabbcdabe";
puts(test_str);
remove_chars(test_str, 'b');
puts(test_str);
return 0;
}
void remove_chars(char *str, const char c)
{
char *write_ptr = str;
while (*str) {
if (*str != c) {
*write_ptr = *str;
++write_ptr;
}
++str;
}
*write_ptr = '\0';
}
Program output:
λ> ./a.out
aaabbcdabe
aaacdae
This should work. It's pretty short and sweet.
int newLen = 0;
int oldLen = strlen(str);
for(int i=0; i<oldLen; i++){
if(str[i] != 'b'){
str[newLen] = str[i];
newLen++;
}
}
str[newLen] = '\0';
am writing a program to find a substring in a string. For some strange reason, during comparison of one character to another, two similar characters do not match. I'm not sure if this is some sort of bug.
Here's the code:
#include <stdio.h>
int first_char_compare(char *str,char a);
int main()
{
int i,j, char_exists,substring;
char string1[] = "jrsfahamfsf";
char string2[] = "ham";
char_exists = first_char_compare(string1,string2[0]);
if(!(char_exists<0))
{
j=char_exists;
for(i=0;string2[i]!='\0';i++)
{
for(;string1[j]!='\0';j++)
{
printf("%c\t%c\n",string2[i],string1[j]);
if(string1[i]==string2[j])
{
substring = 1;
printf("matches\n");
break;
}
else
{
printf("doesn't match\n");
substring = 0;
}
}
if(substring==0)
break;
j++;
}
}
if(substring)
printf("Is a substring\n");
else
printf("Not a substring\n");
return 0;
}
int first_char_compare(char *str,char a)
{
/* Checks if the first character of the substring is in the main string.
* If the character exists, it's index is returned. If it doesn't exist
* -1 is returned.
*/
int i;
for(i=0;str[i]!='\0';i++)
{
if(a==str[i])
return i;
}
return -1;
}
In your loops, string2 is indexed by i, and string1 by j:
for (i = 0; string2[i] != '\0'; i++)
{
for( ; string1[j] != '\0'; j++)
{
But in your comparison, the indices are backwards:
if (string1[i] == string2[j])
correct that to:
if (string1[j] == string2[i])
I wrote the following function for removing duplicate characters from a string..For ex: if
str = "heeello;
removeDuplicate(str)
will return helo...But it shows some error on runtime .I have added some printf() statements for debugging...Can anyone tell me what the problem is ?
char* removeDuplicate(char str[])//remove duplicate characters from a string,so that each character in a string is not repeating
{
int i = 0,j;
char ch;
printf("\nstr is %s",str);
while((ch = str[i++] )!= '\0')
{
j = i;
printf("\n----ch = %c----",ch);
while(str[j] != '\0')
{
printf("\n--------Checking whether %c = %c \n",str[j],ch);
if(ch == str[j])
{
printf("\n------------Yes");
while(str[j]!='\0')
{
printf("\nRemoving %c %d -- \n",str[j]);
str[j] = str[++j];
--i;
}
break;
}
printf("\n------------No");
//printf("\njj");
j++;
}
}
return str;
}
You are passing a string literal, which you are not allowed to modify to this function, instead you should do:
char myStr[] = "heee";
removeDuplicate(myStr);
Also, please note that in the following lines your have to specifiers inside the printf (%c %d), but you pass only one argument (str[j]):
printf("\nRemoving %c %d -- \n",str[j]);
This may cause all sorts of bad things...
You should correct your code as follows:
In first while loop: j = i+1;
In third while loop: i--; // is not required
Remove that unwanted specifier form printf("Removing %d %d:",str[j])
Doing incorrectly :
str[j] = str[++j] // you are increasing j before assigning
str[j] = str[j++] // correct way to do.But it is compiler dependent i guess
Better to use:
t = j;
str[t] = str[++j];
I don't think this function does what you want. The remove loop is really fishy.. you decrement i which looks wrong.. and you increment j which is probably also wrong:
while(str[j]!='\0')
{
printf("\nRemoving %c %d -- \n",str[j]);
str[j] = str[++j]; // now the new character is at location j, but since
// you incremented j you can't access it anymore
--i; // why is i dependent on the remove stuff?
}
I would go for a simpler approach. Create a large bool array. Loop through your string and store whether you already encountered the current character or not. If not, print it.
Check the following code :
char* removeDuplicate(char str[])//remove duplicate characters from a string,so that each character in a string is not repeating
{
int i = 0,j;
char ch;
int repIndex=0;
int temp=0;
printf("\nstr is %s",str);
while((ch = str[i++] )!= '\0')
{
j = i;
printf("\n----ch = %c----",ch);
while(str[j] != '\0')
{
printf("\n--------Checking whether %c = %c \n",str[j],ch);
repIndex = j;
if(ch == str[repIndex])
{
printf("\n------------Yes");
while(str[repIndex]!='\0')
{
printf("\nRemoving %c %d \n",str[j]);
temp = repIndex;
str[temp] = str[++repIndex];
}
} else { j++; }
}
}
return str;
}
int main ( int argc, char ** argv)
{
char myStr[]="asdfhelllasdfloofdoeohz";
printf ("OUtput is : %s \n", removeDuplicate(myStr) );
}
//removing the redundant characters in a string
#include<stdio.h>
int main()
{
int i=0,j,arr[26]={},temp; //array for hashing
char s[10],arr1[10],*p; //array 4 storing d output string
printf("Enter the string\n");
scanf("%s",s);
p=s;
while(*p!='\0')
{
temp=((*p)>92)?(*p)-'a':(*p)-'A'; //asuming lowr and upr letters are same
if(arr[temp]==0) //if it is not hashed ie if that char is not repeated
{
arr1[i]=temp+'a'; //return the string in lowecase
arr[temp]=1; //storing value so that this character sd not be placed again
i++;
}
p++; //else ignore the alphabet
}
for(j=0;j<i;j++)
{
printf("%c",arr1[j]); //print the string stored in arr1
}
return 0;
}
I have corrected the code as follows
char* removeDuplicate(char str[])//remove duplicate characters from a string,so that each character in a string is not repeating
{
int i = 0,j;
char ch;
while((ch = str[i++] )!= '\0')
{
j = i;
while(str[j] != '\0')
{
if(ch == str[j])
{
while(str[j]!='\0')
str[j] = str[++j];
i--;
break;
}
j++;
}
}
return str;
}
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
#include<string.h>
void main()
{
clrscr();
char *str;
int count=0;
cout<<"enter the string which have repetative characters"<<endl;
cin>>str;
char *str2;
int m=0;
for(int i=0;i<=strlen(str);i++)
{
char ch=str[i];
if(i==0)
{
str2[m]=str[i];
m++;
}
for(int j=0;j<=strlen(str2);j++)
{
if(ch==str2[j])
count++;
}
if(count==0)
{
str2[m]=str[i];
m++;
}
count=0;
if(i==strlen(str))
str2[m]='\0';
}
puts(str2);
getch();
}
O(n) complexity
char *removeDuplicates(char *str){
int hash[256] = {0};
int currentIndex = 0;
int lastUniqueIndex = 0;
while(*(str+currentIndex)){
char temp = *(str+currentIndex);
if(0 == hash[temp]){
hash[temp] = 1;
*(str+lastUniqueIndex) = temp;
lastUniqueIndex++;
}
currentIndex++;
}
*(str+lastUniqueIndex) = '\0';
return str;
}
Refer: http://www.geeksforgeeks.org/remove-all-duplicates-from-the-input-string/
The definition of library function strspn is:
size_t strspn(const char *str, const char *chars)
/* Return number of leading characters at the beginning of the string `str`
which are all members of string `chars`. */
e.g. if str is "fecxdy" and chars is "abcdef" then the function would return 3, since f, e and c all appear somewhere in chars, giving 3 leading characters of str, and x is the first character of str which is not a member of chars.
Could someone help me write an implementation of strspn in C. The only library function I am allowed to call from the implementation is strlen?
The basic idea is to step through the string, one character at a time, and test if it's in the character set. If it's not, stop and return the answer. In pseudocode, that would look like:
count = 0
for each character c in str
if c is not in chars
break
count++
return count
The if c is not in chars test can be implemented by iterating through all of the characters of chars and testing if c matches any of the characters. Note that this is not the fastest implementation, since it involves stepping through the chars string for each character in str. A faster implementation would use a lookup table to test if c is not in chars.
I found this question while going over old exams. You weren't allowed to use indexing or any standard functions. Here's my attempt at a solution:
#include <stdio.h>
size_t myStrspn(const char *str1, const char *str2){
size_t i,j;
i=0;
while(*(str1+i)){
j=0;
while(*(str2+j)){
if(*(str1+i) == *(str2+j)){
break; //Found a match.
}
j++;
}
if(!*(str2+j)){
return i; //No match found.
}
i++;
}
return i;
}
void main(){
char s[] = "7803 Elm St.";
int n = 0;
n = myStrspn(s,"1234567890");
printf("The number length is %d. \n",n);
}
Here's the solution from the exam:
#include<stdio.h>
size_t strspn(const char* cs, const char* ct) {
size_t n;
const char* p;
for(n=0; *cs; cs++, n++) {
for(p=ct; *p && *p != *cs; p++)
;
if (!*p)
break;
}
return n;
}
For loops made it much more compact.
I think this should be pretty fast
size_t strspn(const unsigned char *str, const unsigned char *chars){
unsigned char ta[32]={0};
size_t i;
for(i=0;chars[i];++i)
ta[chars[i]>>3]|=0x1<<(chars[i]%8);
for(i=0;((ta[str[i]>>3]>>(str[i]%8))&0x1);++i);
return i;
}
Thanks to others for sanity checks.
A naive implementation of strspn() would iterate on the first string, as long as it finds the corresponding character in the second string:
#include <string.h>
size_t strspn(const char *str, const char *chars) {
size_t i = 0;
while (str[i] && strchr(chars, str[i]))
i++;
return i;
}
Given that you are not allowed to call strchr(), here is a naive native implementation:
size_t strspn(const char *str, const char *chars) {
size_t i, j;
for (i = 0; str[i] != '\0'; i++) {
for (j = 0; chars[j] != str[i]; j++) {
if (chars[j] == '\0')
return i; // char not found, return index so far
}
}
return i; // complete string matches, return length
}
Scanning the second string repeatedly can be costly. Here is an alternative that combines different methods depending on the length of chars, assuming 8-bit bytes:
size_t strspn(const char *str, const char *chars) {
size_t i = 0;
char c = chars[0];
if (c != '\0') { // if second string is empty, return 0
if (chars[1] == '\0') {
// second string has single char, use a simple loop
while (str[i] == c)
i++;
} else {
// second string has more characters, construct a bitmap
unsigned char x, bits[256 / 8] = { 0 };
for (i = 0; (x = chars[i]) != '\0'; i++)
bits[x >> 3] |= 1 << (x & 7);
// iterate while characters are found in the bitmap
for (i = 0; (x = str[i]), (bits[x >> 3] & (1 << (x & 7))); i++)
continue;
}
}
return i;
}
int my_strspn(const char *str1,const char *str2){
int i,k,counter=0;
for(i=0;str1[i]!='\0';i++){
if(counter != i) break;
for(k=0;str2[k]!='\0';k++){
if(str1[i]==str2[k])
counter++;
}
}
return counter;
}
Create a lookup table (a poor man's set) for all possible ASCII chars, and just lookup each character in str. This is worst case O(max(N,M)), where N is the number of characters in str and M is the number of characters in chars.
#include <string.h>
size_t strspn(const char *str, const char *chars) {
int i;
char ch[256] = {0};
for (i = 0; i < strlen(chars); i++) {
ch[chars[i]] = 1;
}
for (i = 0; i < strlen(str); i++) {
if (ch[str[i]] == 0) {
break;
}
}
return i;
}
This could also be solved without using strlen at all, assuming both strings are zero-terminated. The disadvantage of this solution is that one needs 256 bytes of memory for the lookup table.
Without touching a C-compiler for the last couple of years. From the top of my head something like this should work:
int spn = 0;
while(*str++ != '\0')
{
char *hay = chars;
bool match = false;
while(*hay++ != '\0')
{
if(*hay == *str)
{
match = true;
break;
}
}
if(match)
spn++;
else
return spn;
}
return spn;
Well, implementing a standard library for my OS, here is my solution (C++).
KCSTDLIB_API_FUNC(size_t DECL_CALL strspn(const char * str1, const char * str2))
{
size_t count = 0;
auto isin = [&](char c)
{
for (size_t x = 0; str2[x]; x++)
{
if (c == str2[x])
return true;
};
return false;
};
for (; isin(str1[count]); count++);
return count;
}