Search code examples
algorithmkotlinconsolecommand-promptmergesort

Get program starting console parameters without String Array


I'm making a merge sort algorithm for a school project and I have to do it in 2 different ways. In one of them the only data structure I can use are arrays, and in another I can't use arrays. I've managed to do it both ways with only 1 part which I can't figure out how to do, the program must be started with console parameters i.e. kotlin JoinFiles1.kt Output.txt Input_1.txt ... Input_n.txt, with JoinFiles being my program, and in the method I have to use arrays I simply pass the main function with the normal String array, fun main(args: Array<String>) and then use args to be able to access the files, but since I can't use Arrays in the second method, I'm not exactly sure how to read the files through console. Help's appreciated!

Code so far

    fun main(args: Array<String>) {
// ler as palavras de todos os arquivos de entrada e juntá-las em um array
var nficheiros = args.toMutableList()
var palavras = mutableListOf<String>()
for (nficheiro in nficheiros) {
    val file = File(nficheiro)
    file.forEachLine { line ->
        palavras.add(line)
    }
}
mergeSort(palavras)

    // remover palavras duplicadas mantendo apenas uma ocorrência de cada palavra
    var unicas = mutableListOf<String>()
    for (palavra in palavras) {
        if (!unicas.contains(palavra)) {
            unicas.add(palavra)
        }
    }

    // escrever as palavras no arquivo de saída
    val pw = createWriter(args[0])
    unicas.forEach { palavra ->
        pw.println(palavra)
    }
}

// algoritmo de merge sort para ordenar a mutableList de palavras
fun mergeSort(mList: MutableList<String>) {
    if (mList.size > 1) {
        val meio = mList.size / 2
        val esq = mList.subList(0, meio)
        val dir = mList.subList(meio, mList.size)
        mergeSort(esq)
        mergeSort(dir)
        var i = 0
        var j = 0
        var k = 0
        while (i < esq.size && j < dir.size) {
            if (esq[i] <= dir[j]) {
                mList[k] = esq[i]
                i++
            } else {
                mList[k] = dir[j]
                j++
            }
            k++
        }
        while (i < esq.size) {
            mList[k] = esq[i]
            i++
            k++
        }
        while (j < dir.size) {
            mList[k] = dir[j]
            j++
            k++
        }
    }
}

Created a bufferedreader but not sure how to get the file names without using the array.


Solution

  • You should probably ask your teacher, but I feel like it's ok to use an array for accessing the commandline arguments - I'm not sure there's another way to do it! You're just implementing the standard main function which has an args parameter that passes you an Array<String> (there's also the shorthand main() version with no parameters, that's for when you don't need to read any arguments). This is standard boilerplate, you don't really have any choice!

    I assume the "no arrays" rule is meant to apply to your algorithm - how you store and process the data you're working with. Same goes for the "only arrays" one - and looking at your code, your mergeSort function is using MutableLists, which aren't Arrays. So that might be fine for your "no arrays" solution, but not for the "arrays only" one.

    Basically the reason these questions are usually set is because there are different ways to approach working with data - arrays are a fixed size and elements can be modified, so that gives you a single object you can update, or swap elements around in. Other collections, e.g. an immutable list, can be transformed into a new object with different data, meaning you're creating new versions of the data and leaving the old one unchanged. Two different approaches with pros and cons. So it might be worth talking to your teacher and asking what they want, in general - what kind of solutions they expect to see. It's possible to treat a MutableList exactly like an Array but is that the point here?