合并有交集的集合

本文转自CSDN-合并有交集的集合

问题

给定一个字符串的集合,格式如:

要求将其中交集不为空的集合合并,合并完成后的集合之间无交集,例如上例应输出:

思路

初始化一个值全为-1, 大小跟给定的字符串集合大小一样的数组(下文叫定位数组)。然后把所有字符串转换成这种形式(字符串和字符串所出现在的集合的索引) 下文叫索引数组的集合

a	0
b	0,1
c	0
d	1,4
e	2
f	2
g	3
h	4

先对索引数组的集合进行排序(没有排序会影响结果), 然后循环索引数组的集合操作定位数组( 如果索引数组大小为1, 且定位数组的当前值的位置的值为-1, 则在定位数组的当前值的位置插入当前值, 如果当前值位置的值不为-1, 则不做操作;如果索引数组有多个元素, 则依次循环每个索引,找到索引数组在定位数组里面的最小值插入

a	0				[  0, -1, -1, -1, -1] 
c	0				[  0, -1, -1, -1, -1]
b	0,1				[  0,  0, -1, -1, -1] 
d	1,4				[  0,  0, -1, -1,  0]
e	2				[  0,  0,  2, -1,  0]
f	2				[  0,  0,  2, -1,  0]
g	3				[  0,  0,  2,  3,  0]
h	4				[  0,  0,  2,  3,  0]

最后这个结果数组 [0, 0, 2, 3, 0] 就是我们想要的

  • 位置为 0,1,4 为一组,合并后为
  • 位置 2 为一组, 即
  • 位置 3 为一组, 即

scala代码实现

def fix(): Unit = {
    val data: Array[Set[String]] = Array(
      Set("a", "b", "c"), 
      Set("b", "d" ), 
      Set("e", "f"), 
      Set("g"), 
      Set("d", "h")

    )
    // 初始化一个跟groupWithSrc一样大小的数组, 全为-1
    val array = List.fill[Int](data.length)(-1).toArray
    val map = mutable.HashMap[String, ArrayBuffer[Int]]()

    for (i <- data.indices) {
      data(i).foreach(s => {
        if (map.containsKey(s)) { // 如果已经存在
          map(s).append(i) // 在原来的基础上增加现在的索引
        } else {
          map.put(s, ArrayBuffer(i))
        }
      })
    }

    val values = map.values
      .toList.sortWith((a, b) => a.mkString("") < b.mkString("")) // 排序
    println(values)

    values.foreach(v => {
      val indexs: ArrayBuffer[Int] = v.sortWith((a, b) => a < b)
      indexs.foreach(i => {
        val arrayI = array(i)
        if (indexs.size == 1) {
          if (arrayI == -1) { // 如果index只有一个而且位置为-1则直接插入
            array(i) = i
          }
        } else { // 如果index不止一个
          val indValues = indexs.map(array(_)).filter(_ != -1)
          val min = if (indValues.isEmpty) i else indValues.min  // 找到所有索引位置最小的值, 如果没有就当前值
          if (arrayI == -1) { //如果位置为-1 则直接插入
            array(i) = min
          } else { // 如果位置已经有值, 则比对原值是否比现在值小, 插入小的
            array(i) = if (arrayI < min) arrayI else {
              values.foreach(arr => {  // 如果有改动, 则所有包含这个索引的都需要改动
                if (arr.contains(i)){
                  arr.foreach(ei => array(ei) = min)
                }
              })
              min
            }
          }
        }
      })
    })

    val tmap = new mutable.HashMap[Int, ListBuffer[Int]]()
    for (i <- array.indices) {
      val e = array(i)
      if (tmap.containsKey(e)) {
        tmap(e).append(i)
      } else {
        tmap.put(e, ListBuffer(i))
      }
    }

    var newBuffer = new ListBuffer[Set[String]]
    tmap.values.foreach(v => {
      var set: Set[String] = Set()
      v.foreach(set ++= data(_))
      newBuffer.append(set)
    })

    println(newBuffer)
  }
posted @ 2019-10-16 18:07  常规操作  阅读(599)  评论(0编辑  收藏  举报