Fork me on GitHub
如何避免变量在多线程中冲突

字符串去重的再研究

 
1、前言
      今天参加了 某公司的在线笔试,其实题目很简单,一道是关于数组去重,另外一道就是字符串替换的问题。这些问题都是网上很常见的问题,但是答的并不是很理想,如果打分的话只能得到70分,面试官也说我的编程水平中等,这样的评价我是完全认同的。现在就回过头来用多种办法求解这两道题吧。
2、数组去重
方法1:使用hash的方法解决该问题
<span style="font-size: 14px;"><strong>2.1.1 初次写出的代码</strong>
Array.prototype.unique = function(){
  var arr = this, obj = {}, result ,i, len = arr.length;
  for(i=0 ; i<len; i++){
       if(!obj[arr[i]]){
           obj[arr[i]] = true;
      result.push(arr[i]);
       }
    }
    return result;
}
</span>

 这是我第一次写的代码,咋一看没什么问题,但是请看下面这个例子

<span style="font-size: 14px;">var a = ['a','b','a','c',3,5,8,3,'8']
a.unique()  //  ['a','b','c',3,5,8]
</span>

但是我们期望的结果是什么呢?自然是['a','b','c',3,5,8,'8'],至于什么原因大家都明白。下面是当时我写的很2的方法: 

<span style="font-size: 14px;"><strong>2.1.2 第一次修bug</strong>
Array.prototype.unique=  function(){
     var arr = this, obj1 = {}, obj2 = {}, result = [], i , len = arr.length;
     for(i=0; i< len; i++){
         if(typeof arr[i] === 'number'){
              if(!obj1[arr[i]]){
           obj1[arr[1]] = true;
                 result.push(arr[i]);
              }
          }else{
              if(!obj2[arr[i]]){
                  obj2[arr[i]] = true;
                  result.push(arr[i]);
              }
          }
       }
       return  result;
}
var a = ['a','b','a','c',3,5,8,3,'8']
var b = a.unique(); //['a','b','c',3,5,8,'8']
</span>

 


IQ太低,上面的代码太土,太2,现在想想看还有没有其他办法。

<span style="font-size: 14px;"><strong>2.1.3 第二次修bug</strong>
Array.prototype.unique=  function(){
    var arr = this, obj = {}, result = [], i , len = arr.length;
    for(i=0; i< len; i++){
     if(<span style="color: #ff6600;">obj[arr[i]] !== arr[i]</span> ){
          <span style="color: #ff6600;">obj[arr[i]] = arr[i]</span>;
          result.push(arr[i]);
     }
    }
    return result;
}
var a = ['a','b','a','c',3,5,8,3,'8'];
var b = a.unique();  // ['a','b','c',3,5,8,'8']
</span>

 


接下来问题来了,假如存在这样的数组 var a = ['a','b','a','c',3,5,8,3,'8',8];你妈这又出现问题了,结果为['a','b','c',3,5,8,'8',8],那就都存起来:

<span style="font-size: 14px;"><strong>2.1.4 第三次修bug</strong>
if(!Array.prototype.indexOf){
    Array.prototype.indexOf = function(ele,index){
        var arr = this, len = arr.length, index = index >= 0 ? index : index + len ,i;
        for(i=index; i < len; i++){
            if(arr[i] === ele){
              return i;
            }
        }
        return -1;
    }
}
 
Array.prototype.unique=  function(){
    var arr = this, obj = {}, result = [], i , len = arr.length;
    for(i=0; i< len; i++){
        obj[arr[i]] = obj[arr[i]] || [];
        if(obj[arr[i]].indexOf(arr[i]) === -1 ){
              <span style="color: #ff6600;"> obj[arr[i]].push(arr[i])</span>;
               result.push(arr[i]);
        }
    }
    return result;
}
var a =  ['a','b','a','c',3,5,8,3,'8',8];
var b = a.unique(); // ['a','b','c',3,5,8,'8'] 到目前为止应该不会出现bug了
</span>
方法2:使用indexOf方法或者lastIndexOf方法
     这个方法需要考虑到低版本的浏览器是不知道indexOf属性的,所以使用前非常有必要写下兼容性的代码:
<span style="font-size: 14px;">if(!Array.prototype.indexOf){
    Array.prototype.indexOf = function(ele,index){
        var arr = this, len = arr.length, index = index >= 0 ? index : index + len ,i;
        for(i=index; i < len; i++){
            if(arr[i] === ele){
              return i;
            }
        }
        return -1;
    }
}
Array.prototype.unique=  function(){
    var arr = this, obj = {}, result = [], i , len = arr.length , n;
    for(i=0; i< len; i++){
        n = <span style="color: #ff6600;">arr.indexOf(arr[i],i+1)</span>;
        if( n !== -1){
            <span style="color: #ff6600;">arr.splice(n,1)</span>;
        }
    }
    return arr;
}
var a =  ['a','b','a','c',3,5,8,3,'8',8];
var b = a.unique();  //['a','b','c',3,5,8,'8']</span>
现在想出来的也就这两种方法了。 

【多线程】在暴力破解中的应用问题---如何避免变量在多线程中冲突(都是调用同一个值)【请各位指点一下!】 - CSDN论坛 - CSDN.NET http://bbs.csdn.net/topics/390603941

 

TianYi3G2013 - 博客园 http://www.cnblogs.com/TianYi3G2013/

 

两边同时发,看看哪个社区的更热心~~~~

为方便各位帮忙调试,特附上源码:

Thread.zip_免费高速下载|百度云 网盘-分享无限制 http://pan.baidu.com/s/1zKA4Y

复制代码
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 
  6 using System.Threading;
  7 
  8 
  9 
 10 namespace ThreadStu
 11 {
 12     /// <summary>
 13     /// 学习如何避免变量在多线程中冲突(都是调用同一个值)
 14     /// 
 15     /// 【参考】:
 16     /// 蜘蛛爬虫多线程控制 - Robin99 - 博客园
 17     ///http://www.cnblogs.com/yinhaiming/articles/1533700.html
 18     /// 
 19     /// </summary>
 20     class Program
 21     {
 22         private static int pwd = 321;              //假设密码是321(我们一开始并不知道),现在要求利用多线程来暴力穷举它出来;
 23         private static int startNum = 1;           //假设从1开始穷举
 24         private static int count = 0;              //穷举次数; 
 25                 
 26         static void Main(string[] args)
 27         {
 28             //ThreadStart startCalu = new ThreadStart(calc);
 29             //线程开始,即每个线程都执行calc();
 30             //Thread calcThread = new Thread(startCalu);
 31             //实例化要开启的新类;
 32             //calcThread.Start();
 33             //开启线程;
 34 
 35 
 36 //         由于线程起始时启动的方法不能带有参数,这就为多线程调用同一个方法添加了麻烦。
 37 //         知道开启多线程下载的方法后,大家可能会产生几个疑问:
 38 //1.       如何控制线程的数量?
 39 //2.       如何防止多线程执行时startNum变量都是从同一数值开始以及如果防止变量count冲突(如线程1的count已经到达98了,线程2实际才10,也跟着结束了。。)?
 40 
 41 //3.       如何控制线程结束?
 42 
 43 
 44 //            下面就这几个问题提出解决方法:
 45 //1.       线程数量我们可以通过for循环来实现
 46 
 47             //比如已知用户指定了n(它是一个int型变量)个线程吧,可以用如下方法开启五个线程
 48             
 49 
 50             Thread[] calcThread;
 51          //声明下载线程,这是C#的优势,即数组初始化时,不需要指定其长度,可以在使用时才指定。这个声明应为类级,这样也就为其它方法控件它们提供了可能:
 52             ThreadStart startCalc = new ThreadStart(calc);
 53 
 54             int n = 4;
 55             calcThread=new Thread[n];
 56             //为线程申请资源,确定线程总数;
 57 
 58             for (int i = 0; i < n; i++)
 59             {
 60                 calcThread[i] = new Thread(startCalc);
 61                 //指定线程起始设置;
 62                 calcThread[i].Start();
 63                 //逐个开启线程;
 64             }
 65 
 66 
 67             //2.下面出现的一个问题:所有的线程都调用calc()方法,这样如何避免它们变量startNum都是从相同的数值开始?
 68 
 69             //★ a.这个问题也好解决,只要建立一下startNum地址表,表中的每个地址只允许被一个线程申请即可。
 70             
 71             //具体实现:..不会操作了,请各位帮忙解决!
 72 
 73 
 74             //★ b.去重问题也可以在C#语言内解决,只根建立一个临时文件(文本就可以),保存所有的startNum地址,差对它们设置相应的属性即可,但查找效率可能不及数据库快。
 75 
 76                         
 77 
 78             //4.当所有线程任务完成后,通过for循环结束:
 79 
 80             for (int i = 0; i < n; i++)
 81             {
 82                 calcThread[i].Abort();
 83             }
 84 
 85 
 86 
 87                 Console.ReadLine();
 88 
 89         }
 90         
 91         //如果要达到在第一个线程中,startNum从1开始    
 92         //            第二个线程中,.......从100开始
 93         //            第三个线程,.........从200开始
 94         //            第四个线程,.........从300....
 95         
 96 
 97         //这个startNum的值可以保存在一个文本文件中,只要能达到避免线程冲突就可以了:
 98         static void calc()
 99         {
100             while (count < 100)                     //当一个线程把变量startNum累加100次(如果避免这个count变量线程冲突??)后停止;
101             {
102                 if (startNum != pwd)
103                 {
104                     startNum++;
105                 }
106                 else
107                 {
108 
109 
110 
111                     //xxxxxxxxxxxxxxxxxxxxxxxxxxxx
112                     //当穷举正确后,停止所有线程;
113                     Console.WriteLine(startNum);
114                     Console.ReadLine();
115                 }
116                 count++;
117             }
118 
119         }
120 
121 
122 
123     }
124 }
复制代码

 

在暴力破解中的应用问题---如何避免变量在多线程中冲突(都是调用同一个值)【请各位指点一下!】

posted on 2013-09-29 23:49  HackerVirus  阅读(1405)  评论(0编辑  收藏  举报