第一个只出现一次的字符

  方法1 :
            第一个只出现一次的字符。
           (1)考虑使用一个hash表,将各个字符映射到表中,然后表中存储有该字符出现的次数,以及首次出现的下标。
           (2)映射完成之后,扫描hash数组查找出现次数为1的字符,并且其首次出现下标为最小。

    缺点:

          需要存储首次出现的下标,造成存储位置浪费。

#include <iostream>
#include 
<vector>
#include 
<iterator>
  
using namespace std ;
 
  
struct Value{
     
int times ;
     
int index ;        
  }
 ;
  
const int N = 26 ;
  
const int MAX = 66536 ;
  
int hashstr(char * s , Value * list )
  
{
       
int i = 0 ;
       
int index = MAX ;
       
      
if(s == 0
        
return index;
        
      
while(*!= '\0')
        
{
          list[
*s-'a'].times++ ;
          
if(list[*s-'a'].index == -1//若是首次出现下标,则统计 
            list[*s-'a'].index = i ;           
            i
++;
            s
++;
        }

          
       
       
for(i = 0 ;i < N ; i++)
       
{
         
if(list[i].times == 1)
            
{
              
if(index > list[i].index)   //求最小的下标       
               index = list[i].index ;                     
            }
       
       }

       
return index ;
  }

 
  
int main()
  
{
    
int i ;
  
    
char s[] = "wabacckdeffbzw" ; 
    Value  list[N] ;
   
     
for(i = 0;i < N ;i++)
     
{
       list[i].times 
= 0 ;
       list[i].index 
= -1 ;                     
     }
 
   
    
int index = hashstr(s , list) ;
    
if(index == MAX)
       cout
<<"error"<<endl ;
     
else
       cout
<<s[index]<<endl ;
        
    system(
"pause") ;
    
return 0 ;    
  }

方法2 :

    建立一个长度为256的hash数组,扫描到对应的字符,即更新hash表内存储出现的次 数。
 需要两次扫描字符串,第一次扫描统计字符串的出现次数,第二次扫描确定出现一次的字符及其位置 ,比方法1,比较省空间。 
  代码如下:

#include <iostream>
 
using namespace std ;
 
const int N = 256 ;
 
 
void hashstr(char * s , int * a)
 
{
    
char * p = s ;   
    
while(*p)
    
{
      a[
*p]++ ; //自增       
      p++ ;         
    }
  
    
    
while(*s) //扫描第二遍,当扫描都出现次数为1的字符,即停止 
    {
      
if(a[*s] == 1)
      
{
        cout
<<*s ;
        
break
      }

      s
++ ;         
    }

    
      
 }

 
 
int main()
 
{
   
char s[] = "wabacckdeffbz" ;
   
int  a[N] ;
   memset(a , 
0 , sizeof(a)) ;
   hashstr(s , a) ;
   system(
"pause") ; 
   
return 0 ;    
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值