【问题标题】:Recursive function based on 2 conditions基于 2 个条件的递归函数
【发布时间】:2019-08-30 23:45:05
【问题描述】:

我想编写一个在 2 个条件下退出的递归函数。

假设我想创建一个目录并要求用户输入。他可能会输入这样的内容:

Valid: /existing-dir1/existing-DIR2/non-existence-dir1/non-existence-dir2
Invalid: /existing-dir1/existing-FILE1/non-existence-dir1/non-existence-dir2

要遍历文件名,我有函数dirname(),它接受/foo/bar 并返回/foo。我还有函数exist() 来检查文件名是否存在,isdir() 来查看它是文件还是目录。

基本上,我需要从文件名的末尾递归循环,忽略不存在的节点,并检查是否有任何节点是文件——这是无效的。当两个条件之一发生时,递归结束,以先到者为准:

  1. 找到一个文件
  2. dirname() 返回/

我不熟悉递归,两个条件对我来说有点太多了。我正在使用 POSIX 脚本,但 C++/Java/C# 中的代码示例都很好。

编辑:我知道我可以执行mkdir -p 并获取其状态代码,但它会创建目录。尽管如此,为了学习的目的,我想以递归方式进行。

【问题讨论】:

  • 为什么要从头循环?在我看来,如果你从头开始,如果任何前缀路径代表一个文件,你可以返回invalid,如果你通过整个字符串而没有遇到文件,则返回valid
  • @ScottSauyet 可能是因为预装了dirname 程序,适合从头循环。在 shell 脚本中,工具是有限的,甚至数组也不可用。从头开始循环可能会使代码更复杂一些。我更喜欢使用已有的。
  • 我想递归从头到尾都是一样的。

标签: recursion


【解决方案1】:

在 JS 中,你可以这样写递归:

const isValid = (path) => 
  path === '/' 
    ? 'valid' 
    : exist(path) && !isdir(path) 
      ? 'invalid' 
      : isValid(dirname(path))

根据您的 isdir 函数的工作方式,您也许可以跳过 exist 检查。

这应该显示逻辑,但我不确定如何在您的 Posix 脚本环境中编写它。

【讨论】:

  • 感谢您的回答。我熟悉类似 C 的语法,不能完全理解上面的代码。但是我确实在 15 分钟左右后自己解决了这个问题。我今天下午花了 2 个小时,结果不知道该怎么做才去这里问。
  • 现在我在想第三个条件,即底层目录(从末尾循环时首先找到现有目录)必须是可写的。我想这次我会自己做。
【解决方案2】:

我自己解决了。用 POSIX 脚本编写,但很容易阅读和移植到其他语言:

RecursivelyCheckFilename ()
{
    if [ -e "$1" ]  # if exists
    then
        if [ -d "$1" ]  # if is directory
        then
            if [ "$1" = "/" ]
            then
                return 0;
            else
                RecursivelyCheckFilename "$(dirname -- "$1")";
                return $?;  # returns the value returned by previous function
            fi
        else
            return 1;
        fi
    else
        RecursivelyCheckFilename "$(dirname -- "$1")";
        return $?;
    fi
}

文件名以斜杠结尾仍然存在一些问题,我必须找到解决方法。但上面的代码是我希望它工作的方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-22
    • 1970-01-01
    • 2021-05-03
    • 2019-11-27
    • 2018-10-11
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多