载入中

主元素的线性阶算法

a) 问题
设T[0:n-1]是n个元素的数组。对任意一个元素x,设S(x)={i|T[i]=x}。当|S(x)|〉n/2时,称x为T的主元素。设计一个线性时间算法,确定T[0:n-1]是否有一个主元素。
b) 分析
通过对问题目的性的研究,可以得到这样的一个结论:
在元素数组中,删去不同的两个元素,数组的主元素保持不变。
按照这样的思路,我们可以不断缩小问题的规模,最终使问题得解:
设置变量Seed用于存储当前候选元素,初始化为数组首元素a[0];
设置变量count用于控制候选元素,初始化为1;
从第二个元素a[1]开始遍历数组,并与Seed相比较:
相同,则count加1,读入下一个元素;
不同,则count减1,读入下一个元素:相当于删去两个不同元素,缩小问题规模;
如果count小于0则Seed不是主元素候选,读入下一个元素,count加1。
这样一次遍历之后,得到的Seed就是主元素的候选;
但因为最终得到的Seed元素有可能是序列最末位的两个元素之一,所以还需要验证。
我们再次遍历数组,得到Seed出现的次数,与总数的一半比较来验证。
c) 编程实现
J***A:

import javax.swing.*; 
 
/** 问题:设T[0:n-1]是n个元素的数组。对任意一个元素x, 
 *设S(x)={i|T[i]=x}。当|S(x)|〉n/2时,称x为T的主元素。 
 *设计一个线性时间算法,确定T[0:n-1]是否有一个主元素。 
 */ 
public class Master 
{ 
     
     final static int maxInput = 100;   //最大处理序列为100 
     /**主程序接受一组整数值,调用hasMaster()判断是否存在主元素。 
     */ 
     public static void main(String args[]) 
     { 
         int data[] = new int[100]; 
         int nInput=0; 
      
         String input,msg; 
      
         try 
         { 
             for(int i=0; i<maxInput; i++) 
             { 
                input =  
                    JOptionPane.showInputDialog
                         ("请输入数据 #"+(i+1)+"\n空白结束"); 
                 
                if((input.trim()).length()==0)  //空白结束 
                    break; 
                 
                nInput = i+1;       //输入计数 
                 
                data[i] = Integer.parseInt(input); 
         
             }  //end of for 
              
             msg = "输入的数列:\n"; 
             for(int i=0; i<nInput; i++) 
             { 
       
          msg+= data[i]+" "; 
                if(i%10==9) 
                    msg+="\n"; 
             } 
              
             msg+="\n"; 
             msg+=(hasMaster(data,nInput)?"有":"没有"); 
             msg+="主元素。";             
              
              
             JOptionPane.showMessageDialog(null, 
                msg); 
  
          
         } 
         catch (Exception ex) 
         { 
            JOptionPane.showMessageDialog
                            (null,ex.getLocalizedMessage()); 
         }   
     }  
      
     /**判断输入的数列是否有主元素
      */ 
     private static boolean hasMaster(int data[], int n) 
     { 
        int count=0;    //保存计数 
        int seed;       //保存参照元素 
         
        seed = data[0]; 
         
        for(int i=1; i<n; i++) 
        { 
            if(seed == data[i])     //如果数据相同,计数加一 
            { 
                count++; 
            } 
            if(seed == data[i]) 
            { 
                if(count>0) 
      
           { 
                    count--;        //如果数据不同,则计数减一 
                                    //相当于删除两个不同的元素 
                                    //不会对主元素造成影响 
                } 
                else 
                { 
                    seed = data[i]; //计数为零时,seed不可能为主元素 
                                    //读入新数据 
                } 
            } //end of if 
        } //end of for 
         
        //因为最终得到的seed元素有可能是序列最末位的两个元素之一 
        //因此,这里还需要验证 
        count = 0; 
        for(int i=0; i<n; i++) 
        { 
            if (seed == data[i]) 
                count++; 
        } 
         
        if(count>(n/2)) 
        { 
            return true; 
        } 
         
        return false;    
         
     } 
} 

2005-11-22 13:12:00 By lazing [ 阅读全文 | 回复(4) | 引用通告 | 编辑 ]

  • 标签:算法 主元素 线性 
  • Re:主元素的线性阶算法

    kingleo(游客)

    very good , it's necessary for me !

    thank you very much !

    2006-7-9 12:53:00 By kingleo(游客) [ 个人主页 | 引用 | 返回 | 删除 | 回复 ]

    Re:主元素的线性阶算法

    pb(游客)不对 你试试 3 4 3 4 4

    2007-9-30 22:14:00 By pb(游客) [ 个人主页 | 引用 | 返回 | 删除 | 回复 ]

    Re:主元素的线性阶算法

    canonwu(游客)Thank you!

    2007-10-8 16:19:00 By canonwu(游客) [ 个人主页 | 引用 | 返回 | 删除 | 回复 ]

    Re:主元素的线性阶算法

    碰碰车(游客)已知条件中未知T[0..n-1]是否有序呀,所以该算法无效

    2008-5-2 4:54:00 By 碰碰车(游客) [ 个人主页 | 引用 | 返回 | 删除 | 回复 ]

    发表评论:
    载入中

    Powered by Oblog.