簡體   English   中英

將代碼從C ++移植到C。如何處理基於矢量和范圍的循環

[英]Porting code from C++ to C. How do I deal with this vector and range based loop

我正在嘗試移植到C。由於C中沒有向量,因此我使用了普通數組,但是我不知道如何處理第18行的基於范圍的循環。

    for (int u : d[i]) if (dfs(rev[u])) {
        par[i] = u;
        rev[u] = i;
        return true;
    } 

完整的代碼:

#include <iostream>
#include <vector>
#include <string>
#include <sstream>

using namespace std;
const int Maxn = 200;
vector<int> d[Maxn];
int par[Maxn];
int rev[Maxn];
bool vs[Maxn];
bool dfs(int i) {
    if (i < 0) return true;
    if (vs[i]) return false;
    vs[i] = true;
    for (int u : d[i]) if (dfs(rev[u])) {
        par[i] = u;
        rev[u] = i;
        return true;
    }
    return false;
}
int main() {
    ios_base::sync_with_stdio(false);
    int n;
    cin >> n;
    string s;
    getline(cin, s);
    for (int i = 0; i < n; i++) {
        getline(cin, s);
        stringstream ss(s);
        vector<int> mk(n, 1);
        mk[i] = 0;
        int x;
        while (ss >> x)
            mk[x] = 0;
        for (int x = 0; x < n; x++)
            if (mk[x])
                d[i].push_back(x);
    }
    memset(par, -1, sizeof par);
    memset(rev, -1, sizeof rev);
    for (bool ok = true; ok; ) {
        ok = false;
        memset(vs, 0, sizeof vs);
        for (int i = 0; i < n; i++)
            if (par[i] < 0) {
                ok |= dfs(i);
            }
    }
    int ans = 0;
    for (int i = 0; i < n; i++)
        ans += (par[i] < 0);
    cout << ans;
}

在C語言中沒有std::vector ,closes將是一個數組。

int array[] = [ 1, 3, 5, 7, 9 ];

for(int i = 0; i < sizeof array / sizeof *array; ++i)
    printf("array[%d] = %d\n", i, array[i]);

如果您得到一個int數組的指針,則還必須傳遞該數組的長度,因為sizeof arr / sizeof *arr僅適用於數組。

void foo(in *array, size_t len)
{
    for(int i = 0; i < len; ++i)
        printf("array[%d] = %d\n", i, array[i]);
}

void bar(void)
{
    int array[] = [ 1, 3, 5, 7, 9 ];

    foo(array, sizeof array / sizeof *array);
}

編輯2

我注意到您已經發布了代碼,並且d被聲明為vector<int> d[Maxn]; 同時考慮您最近的評論

因此,這是向量的數組。 你有什么想法我可以如何考慮C中的數組

有兩種方法可以轉換C中的向量數組。但這取決於您的需求。 例如,如果您知道所有向量都將具有相同的大小(例如int vectsize = 100 ),則可以創建一個大小為1的二維數組

int Maxn = 200;
int vectsize = 100;

int d[Maxn][vectsize];
memset(d, 0, sizeof d); // initialize all elements with 0

// filling the data
for(int i = 0; i < Maxn; ++i)
{
    for(j = 0; j < vectsize; ++j)
        d[i][j] = get_value_for(i, j); 
}

范圍循環非常簡單:

// assuming that the variables i, par, rev are valid, i between 0 and Maxn-1
for(int j = 0; j < vectsize; ++j)
{
    int u = d[i][j];
    if (dfs(rev[u])) {
        par[i] = u;
        rev[u] = i;
        return true;
    } 
}

如果您只知道一個維度,則情況會變得有些復雜,例如,數組中的每個向量都可能具有不同的大小。

d[0].size() --> 10
d[1].size() --> 1
d[2].size() --> 3
...

您可以創建一個指向int的指針數組,但是您必須保留另一個int數組,其長度為每個d[i]向量。

int Maxn = 200;
int *d[Maxn]; // pointer to int[Maxn] arrays
int vectsize[Maxn];

// initializing with 0
memset(d, 0, sizeof d);
memset(vectsize, 0, sizeof vectsize);

// filling the data
for(int i = 0; i < Maxn; ++i)
{
    vectsize[i] = get_length_for(i);
    d[i] = malloc(vectsize[i] * sizeof *d[i]);
    if(d[i] == NULL)
        // error handling

    for(j = 0; j < vectsize[i]; ++j)
        d[i][j] = get_value_for(i, j); 
}

請注意,我在這里(以及上一個示例中)使用get_length_for()get_value_for()作為占位符2

現在,基於范圍的循環將如下所示:

// assuming that the variables i, par, rev are valid, i between 0 and Maxn-1
for(int j = 0; j < vectsize[i]; ++j)
{
    int u = d[i][j];
    if (dfs(rev[u])) {
        par[i] = u;
        rev[u] = i;
        return true;
    } 
}

但是在某些時候,您將必須釋放內存:

for(int i = 0; i < Maxn; ++i)
    free(d[i]);

第三種選擇是使用雙指針並使用malloc / realloc分配內存。 這是更通用的解決方案,但是您必須注意內存管理,這有時可能會很困難,尤其是當您沒有使用C編程太多的時候。 但是在兩個維度都不知道的情況下,這也是可行的方法:

int Maxn = get_some_maxn_value();
int **d, *vectsize;

d = malloc(Maxn * sizeof *d);
if(d == NULL)
    // error handling

vectsize = malloc(Maxn * sizeof *vectsize);
if(vectsize == NULL)
    // error handling,
    // if you exit the function, don't forget
    // to do free(d) first as part of the
    // error handling

// initialize all elements with 0
memset(d, 0, Maxn * sizeof *d);
memset(vectsize, 0, Maxn * sizeof *vectsize);

// filling the data (the same as above)
for(int i = 0; i < Maxn; ++i)
{
    vectsize[i] = get_length_for(i);
    d[i] = malloc(vectsize[i] * sizeof *d[i]);
    if(d[i] == NULL)
        // error handling

    for(j = 0; j < vectsize[i]; ++j)
        d[i][j] = get_value_for(i, j); 
}

在這種情況下,范圍循環將看起來與指針數組完全一樣。 但是釋放內存有些不同:

for(int i = 0; i < Maxn; ++i)
    free(d[i]);
free(d);
free(vectsize);

就像我之前說過的,使用這三種方法中的哪一種取決於原始C ++代碼填充值的方式,向量的長度等。從您發布的C ++代碼來看,您從用戶那里讀取一個整數並存儲它在n 然后,您從用戶那里讀取更多值,然后將向量d[i]推入介於0和Maxn-1之間的所有i 似乎所有向量的最大長度為n ,但是由於

if (mk[x])
    d[i].push_back(x);

它們也可以包含少於n元素。 這就是為什么我認為這里第三個解決方案更可取。


注釋

1在C99之前,不支持可變長度數組 (VLA),因此,如果在變量中包含維,則必須使用malloc分配足夠的內存。 C99支持VLA,但我不確定它們的支持程度和/或您的編譯器是否支持它們。

我個人根本不在我的代碼中使用它們,這就是為什么我真的不知道。 我使用GNU GCC 6.4.0(在Linux上)編譯了此示例,並且它們運行良好。

前兩個選項使用VLA,如果編譯器不支持VLA,則必須使用第三個選項。

有關VLA的更多信息:

2如何真正獲得此值取決於原始的C ++代碼。 到目前為止,我只是非常簡要地介紹了您的C ++代碼。 使用我的示例中的值, get_length_for(0)將返回10, get_length_for(1)將返回1, get_length_for(2)將返回3, get_length_for(2)

假設d [i]是一個向量,這是一個類似的循環:

for (size_t s = 0; s < d[i].size(); s++)
{
    int u = d[i][s];
    if (dfs(rev[u]))
    {
        par[i] = u;
        rev[u] = i;
        return true;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM