Python的过滤器(函数,可迭代)的C等价物是什么?

时间:2014-04-04 20:36:59

标签: python c arrays python-2.7 lambda

我正在尝试将以下Python行转换为C.问题是,对于我来说,公式非常复杂。 cubies是一个长度等于120个小写字符的数组。这是一个示例:

fc = ""
try :
    # Pos 1
    fc += filter(lambda a : 'y' in a and 'b'  in a and 'o' in a, cubies)[0]
    fc += filter(lambda a : 'y' in a and 'o'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'y' in a and 'o'  in a and 'g' in a, cubies)[0]
    fc += filter(lambda a : 'y' in a and 'b'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'y' in a and 'g'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'y' in a and 'b'  in a and 'r' in a, cubies)[0]
    fc += filter(lambda a : 'y' in a and 'r'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'y' in a and 'r'  in a and 'g' in a, cubies)[0]
    # Pos 9
    fc += filter(lambda a : 'o' in a and 'b'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'o' in a and 'g'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'b' in a and 'r'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'g' in a and 'r'  in a and a.count('n') == 4, cubies)[0]
    # Pos 13
    fc += filter(lambda a : 'w' in a and 'b'  in a and 'o' in a, cubies)[0]
    fc += filter(lambda a : 'w' in a and 'o'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'w' in a and 'o'  in a and 'g' in a, cubies)[0]
    fc += filter(lambda a : 'w' in a and 'b'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'w' in a and 'g'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'w' in a and 'b'  in a and 'r' in a, cubies)[0]
    fc += filter(lambda a : 'w' in a and 'r'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'w' in a and 'r'  in a and 'g' in a, cubies)[0]
except IndexError :
    sys.exit("IndexError raised")

我试图使用几个Python到C转换器,例如Cython,但它们要么复杂要么使用,要么它们生成的代码太长而不适合像我这样的C菜鸟。

如果有人能指出正确的文档方向,或者你感觉非常友善,请为我编写一个C语言示例函数。

4 个答案:

答案 0 :(得分:3)

有时候首先将python翻译成sane python更容易:

def find_matching(pattern):
    try:
        # Find the first cube where the cubie faces are a shuffled
        # version of the search faces"
        return next(c for c in cubies if sorted(c) == sorted(pattern))

    except StopIteration:
        # next raises StopIteration if it cannot find anything
        raise ValueError("Could not find pattern {}".format(pattern))


fc = ""
# Pos 1
fc += find_matching('ybonnn')
fc += find_matching('yonnnn')
fc += find_matching('yognnn')
fc += find_matching('ybnnnn')
fc += find_matching('ygnnnn')
fc += find_matching('ybrnnn')
fc += find_matching('yrnnnn')
fc += find_matching('yrgnnn')
# Pos 9
fc += find_matching('obnnnn')
fc += find_matching('ognnnn')
fc += find_matching('brnnnn')
fc += find_matching('grnnnn')
# Pos 13
fc += find_matching('wbonnn')
fc += find_matching('wonnnn')
fc += find_matching('wognnn')
fc += find_matching('wbnnnn')
fc += find_matching('wgnnnn')
fc += find_matching('wbrnnn')
fc += find_matching('wrnnnn')
fc += find_matching('wrgnnn')

现在你所要做的就是实施:

  

找到第一个立方体,其中立方体面是搜索面的混洗版本

这是留给读者的练习

答案 1 :(得分:2)

在Python中,

filter采用一个条件(表示为函数)并针对该条件测试可迭代的每个元素(例如列表)。它返回一个包含满足条件的每个元素的列表。

由于此代码始终采用过滤结果的第一个元素,因此您可以在C中表达类似的内容,如下所示:

char *result;
int i;

for(i=0; i<120; i++) { // where 120 is the length of the array
    if(strchr(cubies[i], 'y') && strchr(cubies[i], 'b') && strchr(cubies[i], 'o')) {
        // Condition passes, set result
        result = cubies[i];
        break;
    }
}
if(i == 120) {
    // No condition passed: throw an error
    fprintf(stderr, "Error: condition failed");
    exit(1);
}

然后使用例如sprintfresult追加到您正在构建的fc字符串中。

答案 2 :(得分:1)

这是一种方法。 (我没有测试过,甚至没有编译过。)

char* fc = NULL;
int fclen = 0;

void appendtofc(const char* str)
{
    if (!str)
        return;

    int len = strlen(str);
    fc = realloc(fc, fclen + len + 1);
    if (!fc)
        /* handle error */;
    strcpy(fc + fclen, str);
    fclen += len;
}

const char* match3(const char** arr, int n, char c1, char c2, char c3)
{
    for (int i = 0; i < n; i++)
    {
        int needc = 7;
        for (const char* p = arr[i]; *p; p++)
        {
            if (*p == c1)
                needc &= ~1;
            else if (*p == c2)
                needc &= ~2;
            else if (*p == c3)
                needc &= ~4;

            if (!needc)
                return arr[i];
        }
    }
    return NULL;
}

const char* match2plus4n(const char** arr, int n, char c1, char c2)
{
    for (int i = 0; i < n; i++)
    {
        int needc = 3, needn = 4;
        for (const char* p = arr[i]; *p; p++)
        {
            if (*p == c1)
                needc &= ~1;
            else if (*p == c2)
                needc &= ~2;

            if (*p == 'n')
                needn--;

            if (!needc && !needn)
                return arr[i];
        }
    }
    return NULL;
}

void appendcubies(const char** cubies, int ncubies)
{
    appendtofc(match3(cubies, ncubies, 'y', 'b', 'o'));
    appendtofc(match2plus4n(cubies, ncubies, 'y', 'o'));
    appendtofc(match3(cubies, ncubies, 'y', 'o', 'g'));
    appendtofc(match2plus4n(cubies, ncubies, 'y', 'b'));
    appendtofc(match2plus4n(cubies, ncubies, 'y', 'g'));
    appendtofc(match3(cubies, ncubies, 'y', 'b', 'r' ));
    appendtofc(match2plus4n(cubies, ncubies, 'y', 'r'));
    appendtofc(match3(cubies, ncubies, 'y', 'r' , 'g' ));
    // Pos 9
    appendtofc(match2plus4n(cubies, ncubies, 'o', 'b'));
    appendtofc(match2plus4n(cubies, ncubies, 'o', 'g'));
    appendtofc(match2plus4n(cubies, ncubies, 'b', 'r'));
    appendtofc(match2plus4n(cubies, ncubies, 'g', 'r'));
    // Pos 13
    appendtofc(match3(cubies, ncubies, 'w', 'b' , 'o' ));
    appendtofc(match2plus4n(cubies, ncubies, 'w', 'o'));
    appendtofc(match3(cubies, ncubies, 'w', 'o' , 'g' ));
    appendtofc(match2plus4n(cubies, ncubies, 'w', 'b'));
    appendtofc(match2plus4n(cubies, ncubies, 'w', 'g'));
    appendtofc(match3(cubies, ncubies, 'w', 'b' , 'r' ));
    appendtofc(match2plus4n(cubies, ncubies, 'w', 'r'));
    appendtofc(match3(cubies, ncubies, 'w', 'r' , 'g' ));
}

答案 3 :(得分:-2)

C没有函数式编程。如果您可以使用C ++,我会说最接近的是带有lambda表达式的remove_if。这是一个演示:

#include <iostream>
#include <list>
#include <string>

using std::string;

int main(int argc, char** argv) {
  std::list<string> cubies = {"hello", "world", "bar", "baz"};
  cubies.remove_if([](const string& s){
    return s.find("a") != string::npos;
  });

  for (const string& s : cubies) {
    std::cout << s << std::endl;
  }
  return 0;
}

输出:

$ clang++ -std=c++11 cubies.cc 
$ ./a.out 
hello
world