day04 - Scratch to find the first character in a string that appears only once

Posted by MisterWebz on Sun, 12 May 2019 08:08:36 +0200

Find the first character in a string that appears only once

Input Description:

Enter a non-empty string

Output description:

Output the first character that appears only once, if output-1 does not exist

Example 1

input

asdfasdfo

output

o

In general, this kind of problem is solved by hashmap, and the whole array is thrown into a hashtable to exchange space for time in order to pursue the most efficient time complexity O(N), of course, O(N_) of violence two-level traversal. Sometimes before doing this, the algorithm of time complexity O(N) will be told not to write. (Anyway, I have encountered it.) If you don't say, you can start with a silly way, step by step. In depth;

therefore

1. Violent Solution O(n^2)

Since the requirement is to discover the first character that appears only once and does not repeat, the double-layer loop structure is adopted. Whether the inner loop traversal is the same as the outer loop traversal is compared one by one, or whether the continuation traversal is excluded until no repetition is found;

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

void findSingle(char *str){
    int i,j;
    int len = strlen(str);
    for(i=0;i<len;i++){
        for(j=i+1;j<len;j++){
            if(str[i] == str[j]){
                break;
            }
            if(j == len - 1){
                printf("%c",str[i]);
                return ;
            }
        }
    }
}

int main(){
    char str[] = "abaccdeff";
    findSingle(str);
    return 0;
}

2. Use find()

  • In fact, the time complexity is still high. It is convenient to use soup instead of changing dressing.
#include <iostream>
#include <string>
using namespace std;

int main(){
    string s;
    int flg = -1;
    while(getline(cin,s)){
        unsigned int i;
        for (i=0;i<s.size();i++){
            if(s.find(s[i])==s.find(s[i])){
                flg = true;
                cout<<s[i]<<endl;
                    break;
            }
        }
        if(i==s.size()){
            cout<< flg << endl;
        }
    }
    return 0;
}

3. Using Ascii Coding

C/C++ characters are encoded by Ascii. A character takes up one byte to represent the eighth power of 2. So C/C++ characters can represent 256 characters. Therefore, an array of 256 characters can be used to save the number of occurrences of each character. Of course, the ASCII value of 256 characters is all between 0 and 255, and the ASCII value of'0', so the record can be represented by the subscript of array. What is the number of characters? Then go through the string once to find the first character that appears only once.

char FindFirstSingleChar(char str[]){
    if(str==NULL||str[0]=='\0') return '\0';//Returns'\0'when the string is empty or empty
    int count[256]={0};//Make all characters appear 0 times
    int n=0;
    while(str[n]!='\0'){
        count[str[n]]++;//The number of occurrences of this character plus 1
        n++;
    }
    n=0;
    while(str[n]!='\0'){
        if(count[str[n]]==1){//Find the first character that appears only once
            return str[n];
        }
        n++;
    }
    return '\0';//Returns'\ 0'when there is no character that appears only once in a string
}

4. Common optimization tools - space for time - hashtable

That is, we only traverse the string once, and then record the number of occurrences of each character. For strings, the hash table is usually used, and then the hash table can be queried. If only for strings in lowercase letters, simply use int hashtable [26]= {0}; for storage. But this kind of scenario is relatively few and not universal enough.

void findSingle(char *arr){  
    int hashtable[26] = {0};  
    int i;  
    int len = strlen(str);
    for(i=0;i<len;i++)  
        hashtable[arr[i]-'a']++;  

    for(i=0;i<len;i++){  
        if(hashtable[arr[i]-'a'] == 1){  
            printf("%c\n",arr[i]);  
            break;  
        }  
    } 
    if(i >= len){  
      return -1;
    }  
}  
  • Similarly, if not only line-to-lowercase letters, but also all kinds of characters, it is more general to use int hashtable [256]= {0} directly.
#include<iostream>
#include<string>
using namespace std;
const int Tabsize = 256;
int hashtab[Tabsize];
int main(){
    string str;
    while(cin>>str){
        bool flg = false;
        for(int i=0;i<Tabsize;++i) {
            hashtab[i]=0;
        }
        for(int i=0;i<str.size();++i){
            hashtab[str[i]]++;
        }
        for(int i=0;!flg && i<str.size();++i){
            if(hashtab[str[i]] == 1){
                cout<<str[i]<<endl;
                flg = true;
                break;
            }
        }
        if(!flg)
            cout<<'-1'<<endl;
    }
    return 0;
}

Topics: ascii