[英]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.