2010-01-29 74 views
0

這是一個神奇的方形發生器,但不知道C++,我有一些困難,把這段代碼轉換:有人可以幫我翻譯這個C++代碼到C嗎?

#include <vector> 
#include <iostream> 
using namespace std; 
//There two series will be on even in case of magic square 
// One of even order will be for multiple of 4 
void BuildDoublyEvenMagicSquare(vector<vector<int> > &mat, int Order); 
//Other of even order will be for multiple of 2 
void SinglyEvenMagicSquare(vector<vector<int> > &mat, int order); 
// For odd order 
void BuildOddMagicSquare(vector<vector<int> > &mat, int Order); 

// For odd order 
void BuildOddMagicSquare(vector<vector<int> > &mat, int Order) 
{ 
    int SqrOfOrder = Order * Order; 
    int start=0, mid=Order/2;  // start position 
    for (int loop=1; loop<=SqrOfOrder; ++loop) 
    { 
    mat[start--][mid++] = loop; 
    if (loop % Order == 0) 
    { 
     start += 2; 
     --mid; 
    } 
    else 
    { 
     if (mid==Order) 
     mid -= Order; 
     else if (start<0) 
     start += Order; 
    } 
    } 
} 

void BuildDoublyEvenMagicSquare(vector<vector<int> > &mat, int Order) 
{ 
    vector<vector<int> > A(Order, vector<int> (Order, 0)); 
    vector<vector<int> > B(Order, vector<int> (Order, 0)); 
    int i, j; 
    //Building of matrixes I and J 
    int index=1; 
    for (i=0; i<Order; i++) 
    for (j=0; j<Order; j++) 
    { 
     A[i][j]=((i+1)%4)/2; 
     B[j][i]=((i+1)%4)/2; 
     mat[i][j]=index; 
     index++; 
    } 
    for (i=0; i<Order; i++) 
    for (j=0; j<Order; j++) 
    { 
     if (A[i][j]==B[i][j]) 
     mat[i][j]=Order*Order+1-mat[i][j]; 
    } 
} 

void BuildSinglyEvenMagicSquare(vector<vector<int> > &mat, int order) 
{ 
    int ho=order/2; 

    vector<vector<int> > C(ho, vector<int> (ho, 0)); 

    // For Order is Odd 
    if (order%2==1) 
     BuildOddMagicSquare(C, order); 

    // For Order is Even 
    else 
    { 
    //For Order is Doubly Even Order 
    if (order % 4==0) 
     BuildDoublyEvenMagicSquare(C, order); 
    //For Order is Singly Even Order 
    else 
     BuildSinglyEvenMagicSquare(C, order); 
    } 
    int i, j, k; 
    for (i=0; i<ho; i++) 
    for (j=0; j<ho; j++) 
    { 
     mat[i][j]=C[i][j]; 
     mat[i+ho][j]=C[i][j]+3*ho*ho; 
     mat[i][j+ho]=C[i][j]+2*ho*ho; 
     mat[i+ho][j+ho]=C[i][j]+ho*ho; 
    } 
    if (order==2) 
    return; 

    vector<int> A(ho, 0); 
    vector<int> B; 

    for (i=0; i<ho; i++) 
    A[i]=i+1; 

    k=(order-2)/4; 
    for (i=1; i<=k; i++) 
    B.push_back(i); 

    for (i=order-k+2; i<=order; i++) 
    B.push_back(i); 

    int temp; 
    for (i=1; i<=ho; i++) 
    for (j=1; j<=B.size(); j++) 
    { 
     temp=mat[i-1][B[j-1]-1]; 
     mat[i-1][B[j-1]-1]=mat[i+ho-1][B[j-1]-1]; 
     mat[i+ho-1][B[j-1]-1]=temp; 
    } 
    i=k; 
    j=0; 
    temp=mat[i][j]; mat[i][j]=mat[i+ho][j]; mat[i+ho][j]=temp; 
    j=i; 
    temp=mat[i+ho][j]; mat[i+ho][j]=mat[i][j]; mat[i][j]=temp; 
} 

int main() 
{ 
    int Order; 
    cout<<"Enter the order of square which you wanna: "; 
    cin>>Order; 
    vector<vector<int> > mat(Order, vector<int> (Order, 0)); 

    // For order less than 3 is meaningless so printing error 
    if (Order<3) 
    { 
    cout<<" Order Of Square must be greater than 2"; 
    return -1; 
    } 

    // For Order is Odd 
    if (Order%2==1) 
     BuildOddMagicSquare(mat, Order); 

    // For Order is Even 
    else 
    { 
    //For Order is Doubly Even Order 
    if (Order % 4==0) 
     BuildDoublyEvenMagicSquare(mat, Order); 
    //For Order is Singly Even Order 
    else 
     BuildSinglyEvenMagicSquare(mat, Order); 
    } 


    // Display Results 

    for (int i=0; i<Order; i++) 
    { 
    for (int j=0; j<Order; j++) 
    { 
     cout<< mat[i][j]<<" " ; 
    } 
    cout<<endl; 
    } 
    return 0; 
} 

例如,我該怎麼用C調用這個函數?

void BuildDoublyEvenMagicSquare(vector<vector<int> > &mat, int Order); 

vector<vector<int> > &mat是什麼意思?

@Omnifarious

我可以使用類似這樣的東西嗎?

int **mat: 
*mat = (int **)malloc(sizeof(int*)*Order); 
for (int i=0;i<Order;i++) 
mat[i] = (int *)malloc(sizeof(int)*Order); 
+5

你爲什麼要轉換它? – Omnifarious 2010-01-29 15:18:43

+0

我不知道C++ ...我必須與我的程序的其他部分(數獨xD) – user261908 2010-01-29 15:22:32

+0

@koal:你應該學習C++。正如Omnifarious的答案所指出的那樣,某些部分不容易轉換爲C. – 2010-01-29 15:26:27

回答

2

有關問題的最後一部分,在C是函數原型應該是這樣的,如果你按照我的建議的休息:

void BuildDoublyEvenMagicSquare(int *mat, int Order); 

實際上有幾種方法可以做到這一點。這裏有一些事情在C中無法完成,所以你必須採取一些稍微不同的方法。最重要的是C++向量。 C++ vector就像一個C數組,但它爲您完成所有內存管理。這意味着,例如,在C中只需添加資源管理頭痛的數組就可以很方便地獲得數組。

的C++聲明:

vector<int> varname(5); 

大致相當於C的聲明:

int varname[5]; 

但在C++中,你可以這樣做:

int randominteger = 7; 
vector<int> varname(randominteger); 

,並用C,這是非法,除非你有一個C99兼容的編譯器(在gcc -std = c99):

int randominteger = 7; 
int varname[randominteger]; 

你不能在C元素的可變數量的陣列,所以你不得不求助於callocmalloc,做你自己的內存管理,像這樣:

/* Not that this is not necessary and shouldn't be done (as it's * 
* prone to memory leaks) if you have a C99 compliant compiler. */ 

int randominteger = 7; 
int *varname = calloc(randominteger, sizeof(int)); 
if (varname == NULL) { 
    /* Die horribly of running out of memory. */ 
} 

在這種情況下,我假設你要將你的數組陣列展開成一個長的C數組,這個數組足夠大以容納答案,以便減少必須管理的內存位數。爲了達到這個目的,我會在main中使用mat = calloc(order * order, sizeof(int));這樣的電話,這也意味着在main結束時,您必須致電free(mat)。我還假設你正在展開數組,以便不再有數組的數組。這意味着你必須要做一些數學運算來將列索引轉換爲數組中的線性索引。類似於row * order + column

您將不得不重複我在main建議的每個函數中建立幻方的步驟,因爲它們每個都創建臨時數組來容納在函數結束時消失的東西。

+0

我認爲C99增加了對長度在運行時確定的數組的支持嗎? – Bill 2010-01-29 17:58:14

+0

@Bill,你是對的!那會在那裏節省很多頭痛。我不知道OP有一個符合C99的編譯器,但是如果他做... – Omnifarious 2010-01-29 18:06:40

+0

我主要是做C++,但是找到一個不符合早期採用的標準的編譯器很常見2000? – Bill 2010-01-31 16:35:15

2

我只是回答問題的最後部分。

vector是C++標準庫中的一個容器。它就像一個數組,可以在滿足時自動調整其大小。

A vector<vector<int> >是一個vector包含vector對象,而後者擁有int

A vector<vector<int> >&是對其的引用。引用就像一個指針,除了你不使用*來訪問實際的內容。因此,您直接將mat視爲「好像」這是一個vector對象,只是它實際上是另一個實例的別名,所以您對它做出的任何更改都會「反射回來」並影響調用者可以看到的內容。引用的

簡單的例子:

void add1(int& n) { 
    ++n; 
} 

int main() { 
    int num = 5; 
    add1(num); 
    // num is 6 here 
} 
0

A C++矢量是像C數組。它增加了一些很好的功能,如可選邊界檢查,當需要增加大小時自動重新分配等等。

A vector <int>大致類似於int []。

載體<矢量<INT> >是像一個int * [],其中每個INT *指向數組。它不像二維數組 - 每個內部矢量可以有不同的大小。

使用&前綴變量使該變量成爲參考。引用就像一個指針,你不必明確解引用。通過引用傳遞參數是一種常見的C++習慣用法,在與通過C中的指針傳遞許多相同的情況下使用。

0

vector是一個自動調整大小的數組。所以vector<vector<int>>將是一個int數組數組,相當於C int*[]&mat是一個參考,類似於指針(實際上我認爲C99支持引用)。然而,在這種情況下,由於傳入的值已經是一個指針,所以並不是真的需要。

那麼在C相當於將

void BuildDoublyEvenMagicSquare(int*[] mat, int Order); 
+0

在C++ 98中,你必須在'>>'之間寫一個空格,否則會出現解析錯誤。在C++ 0x中,空間是可選的。 – 2010-01-29 15:25:00

0

你可以去除#includes和'using namespace std'這一行。現在唯一困難的是你的載體。這裏傳遞的是一個二維數組,它在C中很容易。如果你一開始並不知道邊界,那麼困難的一點就是調整它的大小。這就是爲什麼矢量這麼好 - 你不需要關心。

對於更通用的C++ to C轉換,我建議你得到一本像「C++ for C程序員」這樣的書,並從索引返回。更好的是,從頭到尾學習C++。你可能會發現,如果程序複雜的話,C++中會有一些非常棘手的問題。祝你好運!!

0

向量幾乎是一個C++的數組。有許多方法可以動態調整矢量大小(而不是訴諸於realloc()),但除此之外,這幾乎就是你所看到的。

如果您在參數列表中看到&,則表示「通過參考傳遞此參數」。在例程中的C參數是傳入內容的副本,所以如果修改它們,那麼修改不會超出函數的範圍。但是,如果您修改C++引用參數,那麼您還正在修改調用程序用於該參數的變量。

所以要在C中獲得相當於<vector<vector<int>> & mat的值,您可能會傳遞該參數,如int ** mat[],假設用戶正在傳遞一個指向他們希望處理的int數組數組的指針。不同的是,在例程內部,你的C代碼必須做一個*mat來獲取int數組的數組,而在C++代碼中,他們可以直接使用mat

3

您是否僅限於將項目構建爲C項目?如果你正在編寫好的C代碼(並且它不是C99),你可以毫不費力地將它編譯爲C++。如果您可以將其構建爲C++程序,則可以按原樣使用該功能。

在這種情況下,您真正​​需要知道的是您已獲得vector<vector<int> > mat,並且當您調用您的函數時,它會得到您的結果。然後,您可以將預處理器指令#include <vector>放入您的使用它的文件中,並按照using std::vector進行操作,所有內容都將正常工作。特別是,你可以用mat[i][j]讀出的值,就像你用int陣列以及C.

陣列

有一點需要注意的是,你在後面寫vector<vector<int> >而非vector<vector<int>>,因爲>>會被視爲右移運算符而不是角括號分隔符。這將在C++ 0x中出現,當它出現時(x數字現在嚴格爲十六進制),並且可能在特定的編譯器中被修復。

或者,編寫一個包裝函數,該函數接受向量並將其更改爲一個數組int的數組。爲方便起見,您可以使用mat.size()mat[i].size()查找矢量中的元素數量。

+0

包裝函數的方法也可能工作,如果他一心想保留他的程序的其餘部分在C. – Omnifarious 2010-01-29 15:46:47

+0

@Omnifarious:當然,編譯他想要的功能和包裝(將被聲明爲「extern」C「')成一個小靜態庫並鏈接它。這應該工作正常。 – 2010-01-29 16:09:12

相關問題