• 如何避免变量在多线程中冲突


    字符串去重的再研究

     
    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 }
    复制代码

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

  • 相关阅读:
    204. 计数质数
    236. 二叉树的最近公共祖先
    优先队列和哈夫曼树
    185. 部门工资前三高的所有员工(求组内前几的值)
    部门工资最高的员工(求组内最大值)
    回调函数的案例
    单链表
    动态数组
    一致性哈希算法的基本原理
    只用2GB内存在20亿个整数中找到出现次数最多的数
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3346538.html
Copyright © 2020-2023  润新知