我如何实现这一点;柜台;在JavaScript中的哈希表上?

我如何实现这一点;柜台;在JavaScript中的哈希表上?,javascript,arrays,hashtable,Javascript,Arrays,Hashtable,我正在用JavaScript创建这个哈希表,我希望每次在数组中添加现有值时它都会发出警告。我尝试了自己的实现,但它不起作用 function hashFunction(s,tableSize){ let hash = 17; for(let i = 0; i<s.length; i++){ hash = (13*hash * s.charCodeAt(i)) % tableSize; } return hash; }; class H

我正在用JavaScript创建这个哈希表,我希望每次在数组中添加现有值时它都会发出警告。我尝试了自己的实现,但它不起作用

function hashFunction(s,tableSize){
    let hash = 17;

    for(let i = 0; i<s.length; i++){
        hash = (13*hash * s.charCodeAt(i)) % tableSize;
    }

    return hash; 
};

class HashTable {

    table = new Array(2000);
    numItems  = 0;
    loadFactor = this.numItems/this.table.length;

    setItem = (key,value)=>{
        const idx = hashFunction(key, this.table.length);
        if(this.table.includes(key)){
            return "already exists"
        }else this.numItems++
        if(this.table[idx]){
            this.table[idx].push([key,value])
        }else this.table[idx]=[[key,value]];

    };

    getItem = (key)=>{
        const idx = hashFunction(key,this.table.length);
        if(!this.table[idx]){
            return "Key doesn't exist";
        }else
         return this.table[idx].find(x=>x[0]===key)[1];
    };
};

let myHash = new HashTable

myHash.setItem("first","daniel")
myHash.setItem("last","esposito")
myHash.setItem("age","21")
myHash.setItem("height","1,90")
函数hashFunction(s,tableSize){
设hash=17;
for(设i=0;i{
const idx=hashFunction(key,this.table.length);
if(本表包括(键)){
返回“已存在”
}要不然,我就来++
if(此.table[idx]){
this.table[idx].push([key,value])
}否则,该.table[idx]=[[key,value]];
};
getItem=(键)=>{
const idx=hashFunction(key,this.table.length);
如果(!this.table[idx]){
返回“密钥不存在”;
}否则
返回此。表[idx]。查找(x=>x[0]==key)[1];
};
};
让myHash=新哈希表
myHash.setItem(“第一个”、“丹尼尔”)
setItem(“last”,“esposito”)
myHash.setItem(“年龄”、“21”)
myHash.setItem(“高度”,“1,90”)

hash+=(13*hash*s.charCodeAt(i))%tableSize;
检查实现伪代码和现有实现将是有益的。有许多错误可以总结为原始实现无法正确处理bucket中的对

这是一个正在运行的更新,它挽救了一些结构,同时丢弃了大多数不一致和/或不正确的实现-我留下了注释作为参考点,以了解原始版本不正确的原因。代码的结构说明了bucket的访问/创建、bucket内对的访问/创建,以及avior选择取决于具体情况

YMMV


“它工作得不太好”是什么意思?错误(哪个)或某些操作后输出错误(哪个)?为什么要实现自己的哈希表而不是使用Javascript内置的东西(例如对象或集合)?在这一行
this.table.includes(key)
,您正在将
传递给
表。includes
,但
表。includes
只会告诉您数组是否包含提供的值(
此.table
的值不是哈希键,它们是
[键,值]
数组)。如果您想有效地测试数组中是否存在值(即不在每次检查时搜索数组),则必须创建另一个由值索引的哈希表。然后根据该哈希表进行测试。此外,
13*hash*s.charCodeAt(i)
可能应该是
13*hash+s.charCodeAt(i)
?否则,一旦有了2000的因子,哈希值将永远为零。无论如何,请务必解释“代码片段”的答案,更改是什么,以及更改的相关原因。只使用代码的答案不受欢迎。从长远来看,解释将帮助访问者从您的答案中学习,并确定您的解决方案是否可以应用于解决他们自己的编码问题。高质量、深思熟虑的答案更有可能被高估,因为它们更有用、更快捷请更多的人理解。请考虑编辑来突出您的解决方案的重要部分,以及为什么。“仅限生成结束时的目标空间或散列空间和质量显著降低”。不正确。对于任意大小的整数,产品的mod-n与mod-n产品的mod-n相同。在JavaScript中,
number
是浮点类型,因此此哈希实现实际上更糟糕。好吧,哈希函数可能是键入的(请参阅对问题的评论),但我认为使用mod将散列结果映射到bucket是很常见的。好吧,添加了该评论并修改了建议,然后..就这样吧。谢谢更正。大家好!非常感谢你们的帮助和建议,我是编程新手,非常感谢,这是一个很棒的社区。
function hashFunction(s, tableSize){
    let hash = 17;

    for (let i = 0; i < s.length; i++){
        hash = (13 * hash + s.charCodeAt(i)) % tableSize;
        //                ^-- Ry suggests the original * is a typo.
    }

    return hash; 
};

class HashTable {

  // I've eliminated 'load factor' to cover a basic implementation.
  // See rebalancing, good table size selection, alternative collision
  // resolution strategies, etc.
  // This implementation might pass a CS101 course.

  // Yes, for THIS EXAMPLE the TABLE SIZE IS CHOSEN AS 2.
  // This ensures that there are multiple items per bucket
  // which guarantees the collision resolution paths are invoked.
  // This is a terrible choice in practice.
  table = new Array(2);
  numItems = 0;

  setItem = (key, value)=>{
    const idx = hashFunction(key, this.table.length);
    // set/get should ONLY access simple properties or
    // a BUCKET from the hash code as top-level structures.
    // (Using table.includes(..) here is fundamentally INCORRECT.)
    let bucket = this.table[idx];
    if (bucket) {
      // Existing bucket. Search in HERE to see if the key exists.
      // This should generally be the same code as the "get".
      let pair = bucket.find(x => x[0] === key);
      if (pair) {
        // Same pair, update value.
        pair[1] = value;
        return false; // "existing"
      } else {
        // Add new pair to bucket.
        bucket.push([key, value]);
        this.numItems += 1;
        return true; // "new"
      }
    } else {
      // Create a new bucket and item pair.
      this.table[idx] = [[key, value]];
      this.numItems += 1;
      return true; // "new"
    }
  };

  getItem = (key) =>{
    const idx = hashFunction(key, this.table.length);
    // Code should match close to 'set'
    let bucket = this.table[idx];
    if (bucket) {
      let pair = bucket.find(x => x[0] === key);
      if (pair) {
        // Bucket exists and key exists within bucket.
        return pair[1];
      }
    }

    // The result should be the same if the key doesn't exist because
    // bucket is not found, or if the bucket is found and the
    // key does not exist within the bucket..
    return undefined;
  };
}

let myHash = new HashTable

var items = [
  ["first", "daniel"],
  ["last", "esposito"],
  ["age", 21],
  ["height", 1.9]
]

// Insert multiple values:
// Check to see inserted report true/not,
// and that the numItems is increased appropriately.
for (let run of [1, 2]) {
  for (let i of items) {
   let [k, v] = i;
   var inserted = myHash.setItem(k, v);
   var found = myHash.getItem(k) === v;
   console.log(`run=${run} key=${k} value=${v} inserted=${inserted} numItems=${myHash.numItems} found=${found}` )
  }
}
run=1 key=first value=daniel inserted=true numItems=1 found=true
run=1 key=last value=esposito inserted=true numItems=2 found=true
run=1 key=age value=21 inserted=true numItems=3 found=true
run=1 key=height value=1.9 inserted=true numItems=4 found=true
run=2 key=first value=daniel inserted=false numItems=4 found=true
run=2 key=last value=esposito inserted=false numItems=4 found=true
run=2 key=age value=21 inserted=false numItems=4 found=true
run=2 key=height value=1.9 inserted=false numItems=4 found=true