如何显示项目而不显示重复项

How to display items without showing duplicates

我尝试创建一个带有缩进的文件树而不显示重复的文件。 目前我已经这样做了:

val listOfDisplayPaths : List<String> = listOf(
        "/home/josh/project/app/src/index.js",
        "/home/josh/project/app/images/logo.png",
        "/home/peter/.bashrc",
        "/var/log",
        "/usr/lib/node14",
        "/opt/apache2",
        "/etc/hosts"
)

fun displayPaths(paths: List<String>): String {
    val sb = StringBuilder()
    var pathIndented = ""

    for (p in paths) {
        val path = p.split("/")
        
        for (file in path){
            val index = path.indexOf(file)
            val pathWithoutIndent = sb.append(file + "\n")
            val space = addSpace(index)
            pathIndented = sb.append(String.format(space, pathWithoutIndent)).toString()
        }
    }
    return pathIndented
}

fun addSpace(index: Int): String {
    if (index == 0){
        return "- "
    }
    val space = "    "
    return space.repeat(index)
}

fun main(vararg args: String) {
    displayPaths(listOfDisplayPaths)
}

当前结果:

- home
    josh
        project
            app
                src
                    index.js
                        
- home
    josh
        project
            app
                images
                    logo.png
                        
- home
    peter
        .bashrc
            
- var
    log
        
- usr
    lib
        node14
            
- opt
    apache2
        
- etc
    hosts

预期结果:

- home
    josh
        project
            app
                src
                    index.js
                images
                    logo.png
    peter
       bashrc
- var
    log
- usr
    lib
        node14
- opt
    apache2
- etc
    hosts

如何在保持当前缩进的同时不显示重复的文件标题?

我在没有使用打印的情况下也有这个警告:

solution.kt:88:17: warning: parameter 'args' is never used fun main(vararg args: String){
                                                                    ^

我该如何解决?

编辑:我已经替换了

fun main(vararg args: String) {
    displayPaths(listOfDisplayPaths)
}

作者:

fun main() {
    displayPaths(listOfDisplayPaths)
}

解决警告

提前致谢

这是Trie数据结构的完美应用。您只需将所有路径放入前缀树,然后遍历树创建适当的路径字符串。

UPD:为了提高搜索性能,您可能希望将子项存储为哈希映射而不是列表。

import java.util.LinkedList

class Trie {
    
    data class Node(val value: String, var isFile: Boolean = false, val children: MutableList<Node> = LinkedList<Node>()) {
        fun traversePath(currString: StringBuilder, tabs: Int = 1): String {
            if (tabs == 1) currString.append("- ")
            else repeat(tabs) { currString.append("  ") }
            currString.append("${this.value}")
            currString.append("\n")
            
            if (this.isFile) return currString.toString()
            this.children.forEach { it.traversePath(currString, tabs + 1) }
            return currString.toString()
        }
    }
    
    val root = Node("")
    fun add(path: List<String>) {
        if (path.isEmpty()) return
        var currNode = root
        for (name in path) {
            var nextNode = currNode.children.firstOrNull { it.value == name }
            if (nextNode == null) {
                nextNode = Node(name)
                currNode.children.add(nextNode)
            }
            currNode = nextNode
        }
        currNode.isFile = true
    }
}

val listOfDisplayPaths : List<String> = listOf(
        "/home/josh/project/app/src/index.js",
        "/home/josh/project/app/images/logo.png",
        "/home/peter/.bashrc",
        "/var/log",
        "/usr/lib/node14",
        "/opt/apache2",
        "/etc/hosts"
)

fun displayPaths(paths: List<String>): String {
    val sb = StringBuilder()
    val trie = Trie()
    for (path in paths) trie.add(path.trim('/').split("/"))
    
    for (node in trie.root.children) {
        sb.append(node.traversePath(StringBuilder()))
        sb.append('\n')
    }
    return sb.toString()
}

fun main() {
    println(displayPaths(listOfDisplayPaths))
}