Associated with the intersection of the set

This switched CSDN- associated with the intersection of the set

problem

Given a set of strings, such as the format:
{{A, B, C}, {B, D}, {E, F}, {G}, {D H,}}

Claim wherein the intersection set is not null combined, no set intersection between the completion of the merger, to be output in above example:
{{A, B, C, D, H}, {E, F}, {G}}

Thinking

Initializing a full value of -1, the size of the set of strings with a given array of the same size (hereinafter called positioning array). All set then convert this into a string form (in a character string with the set of indexes occurs) hereinafter called indexed array

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

First rank the set of indexed array (not sorted affect the result), then set the operating cycle of the array positioned array index (current index value, if the array size is 1, and the position of the positioning of the array value is -1, the positioning the value of the current position of the array into the current value if the current position is not the value -1, then no operation; if the index array has more elements are cyclically each index, find the index in the array is positioned inside the array of the smallest values ​​into

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]

This last result array [0, 0, 2, 3, 0] is what we want

  • 0,1,4 position as a group, after the merger {a, b, c, d, h}
  • 2 is a set position, i.e., {e, f}
  • 3 is a set position, i.e., {g}

scala code implementation

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)
  }

Guess you like

Origin www.cnblogs.com/betabear/p/11687245.html