Python算法比较两个排序列表并计算多少个元素是相同的

时间:2018-05-08 02:08:08

标签: python python-3.x algorithm array-merge

我必须设计一种算法,比较两个相同长度的排序列表,并返回它们之间的公共值。

所以如果我有两个列表a = [2,9,15,27,36,40]和b = [9,11,15,23,36,44],算法应该返回3的值为两个清单中都有9,15和36。

我知道使用集合可能更容易,但由于我尝试学习数据结构和算法,我更喜欢用更长的时间(更难的方式)。

我当前的代码使用任何目前无法正常工作的阵列合并算法,因为我仍然对r1和r2感到困惑,尽管我认为它们是阵列中最合适的元素,但我不知道#39;知道如何做到这一点。例如。 r1 = 40(来自列表a),r2 = 44(来自列表b)?

global a
a = [2, 9, 15, 27, 36, 40]

global b
b = [9, 11, 15, 23, 36, 44]

global c
c = []

def merge (a1, a, r1, a2, b, r2, c, list3):
    i = a
    j = b
    k = c
    r1 = 
    r2 = 
    while i <= r1 and j <= r2:
        if a1[i]<=a2[j]:
            a3[k] = a1[i]
            i += 1
        elif a3[k] >= a2[j]:
            j += 1
            k += 1
    while i <= r1:  
        a3[k] = a1[i]
        i += 1
        k += 1 
    while j <= r2:  
        a3[k] = a2[j]
        j += 1
        k += 1  

感谢您的帮助和反馈。

3 个答案:

答案 0 :(得分:2)

好的,如果我正确地阅读了你的问题,你想在两个等长的排序列表中找到共同的元素,并返回公共元素的数量。我在这里使用merge有点困惑。

无论如何,如果这是你想要的算法。由于它已经排序,我们可以简单地遍历两个列表并在线性时间内找到公共元素。

算法:

  • ij成为a1a2的索引,分别初始化为0
  • 如果a1[i] < a2[j]我们知道a1[i] a2中不存在i ji指向相应数组中的最小元素。所以我们向前移动a2[j] < a1[i]
  • a1[i] == a2[j]相同。
  • 如果i,我们找到了一个公共元素,我们将jdef find_common(a1, a2): list_len = len(a1) a3 = [] i = j = 0 while i < list_len and j < list_len: if a1[i] < a2[j]: i += 1 elif a2[j] < a1[i]: j += 1 else: a3.append(a1[i]) i +=1 j +=1 return a3 a = [2, 9, 15, 27, 36, 40] b = [9, 11, 15, 23, 36, 44] print(find_common(a, b)) 推进1并继续直到任一阵列的结尾。

代码

// new piece of code
// urls for given buttons (change it to your needs)
const urls = {
  all: '/url1',
  rookies: '/url2',
  ufra: /'url3'
};

async getDbData(url) {                   // pass the argument here
  const dataResponse = await fetch(url)  // and here
  const dataJson = await dataResponse.json()
  return dataJson
}

const bestBtn = document.querySelector('.jsBestBtnList')

bestBtn.addEventListener("click", function (e) {
    let target = e.target;
    let fetchFn = fetcherObject[target.dataset.fetcher];
    
    // fetch url the same way you are fetching the function
    let arg = urls[target.dataset.fetcher];
    if (fetchFn) {
        fetchFn(arg); // pass the argument here
    }
});

function fetchAll(url){ // pass it here 
  dbApi.getDbData(url)  // here as well
    ...
    ...
    ...

答案 1 :(得分:1)

r1r2只是2个列表的长度 在2个列表上进行简单合并并不像您的示例那么复杂,这是一个简化的合并:

def merge(a1, a2):
    r1, r2 = len(a1), len(a2)
    a3 = []
    i = j = 0

    while i < r1 and j < r2:
        if a1[i] < a2[j]:
            a3.append(a1[i])
            i += 1
        else:
            a3.append(a2[j])
            j += 1

    while i < r1:
        a3.append(a1[i])
        i += 1
    while j < r2:
        a3.append(a2[j])
        j += 1

    return a3

In []:
a = [2, 9, 15, 27, 36, 40]
b = [9, 11, 15, 23, 36, 44]
merge(a, b)

Out[]:
[2, 9, 9, 11, 15, 15, 23, 27, 36, 36, 40, 44]

执行重复计数比这更简单,因为您不需要构建新列表,但这应该为您提供进行此计数的基础,并且仅为O(n)

答案 2 :(得分:1)

使用哈希表可以在线性时间内解决这个问题。

您可以使用python字典在哈希表中存储一个列表,其中键将是元素(在本例中为整数),值将是元素的出现次数。运行时间:O(n)

然后遍历另一个列表并为每个元素执行哈希表查找。保留一个变量来计算公共值。运行时间:O(n)。

为避免计算重复项,在迭代时检查前一个元素是否相同,在这种情况下移动到下一个元素。您需要一个额外的变量来跟踪前一个元素。