使用 C++ 在 Sublime Text 中进行自定义调试以进行竞争性编程
- 竞争性编程是一项心理运动,它使我们能够在给定的约束条件下编写给定的问题。本文的目的是指导每个人如何在比赛期间有效地调试代码。
先决条件:为 C++ 竞争性编程环境设置 Sublime Text
时间是宝贵的东西,在编码比赛中它很重要。编写代码时,确实会出现错误,程序员往往会花费大量时间来调试它。程序员经常在比赛中处理复杂的数据结构,并且需要在给定的时间限制内调试它们。
本文重点介绍如何在比赛期间在 Sublime Text (IDE) 中高效调试 C++ 源代码并节省时间。首先,需要设置我们的 Sublime Text 的文件结构。下面是设置 Sublime Text 文件结构的步骤。
第 1 步:打开崇高文本 并按照以下步骤操作:
1. Create three files:
- file.cpp: The file to write the code.
- inputf.txt: The file where we will be giving the input.
- outputf.txt: The file where the output will be displayed.
2. Now, perform the following steps:
- Select View > Layout > Columns: 3. This will create three columns in the workspace. Move the three files into three columns.
- Select View > Groups > Max Columns : 2 : input.txt and output.txt will get stacked in a single column.
您的 Sublime Text 看起来与此类似:
第二步:在主函数。它用于从 input.txt 文件中获取输入并在 output.txt 文件中显示输出。下面是相同的 C++ 代码片段。
C++
// Declare this function outside
// the main function
void local()
{
// In case of online judges (like
// codechef, codeforces etc) these
// lines will be skipped. In other
// words these lines would be executed
// in Sublime Text only
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
// ONLINE_JUDGE
#endif
}
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Local function
void local()
{
#ifndef ONLINE_JUDGE
freopen("input.txt",
"r", stdin);
freopen("output.txt",
"w", stdout);
// ONLINE_JUDGE
#endif
}
// Driver code
int main()
{
local();
return 0;
}
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Driver code
int main()
{
// Initializing a vector
vector vect = {2, 4, 10,
12, 17};
// First operation
for (auto& x : vect)
{
if (x % 2 == 0)
x += 10;
else
x -= 10;
}
// Second operation
for (auto& x : vect)
x += 2;
// Third operation
for (auto& x : vect)
x += 20;
}
C++
// print function outside the
// main function
void print(vector& vect)
{
cout << "vect " << ' ';
cout << '[' << ' ';
// Print vector elements
for (auto x : vect)
{
cout << x << ' ';
}
cout << ']';
}
C++
// C++ program to implement
// the above concept
#include
using namespace std;
// Print function for debugging
void print(vector& vect)
{
cout << "vect " << ' ';
cout << '[' << ' ';
// Print vector elements
for (auto x : vect)
{
cout << x << ' ';
}
cout << ']';
}
// Driver code
int main()
{
// Initializing a vector
vector vect = {2, 4, 10,
12, 17};
// First operation
for (auto& x : vect)
{
if (x % 2 == 0)
x += 10;
else
x -= 10;
}
// Printing vect elements after
// applying first operation
// Checking the status of vect as
// a part of debugging
print(vect);
// Second operation
for (auto& x : vect)
x += 2;
// Third operation
for (auto& x : vect)
x += 20;
int finalAnswer = 0;
for (auto x : vect)
finalAnswer += x;
// Print the final answer
cout << "\nFinal Answer: " <<
finalAnswer;
return 0;
}
C++
// One print function works for
// all data types. This would work
// even for user defined types if
// operator '>' is overloaded
template
void print(vector vect)
{
// body
}
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Using template so that this
// function works for all data
// types
template void print(
vector& vect)
{
cout << "vect " << ' ';
cout << '[' << ' ';
for (auto x : vect)
{
cout << x << ' ';
}
cout << ']';
cout << '\n';
}
// Driver code
int main()
{
vector vect1 = {2, 4, 10,
12, 17};
for (auto& x : vect1)
{
if (x % 2 == 0)
x += 10;
else
x -= 10;
}
// Printing vect1 elements
print(vect1);
// Initializing a vector of
// string type
vector vect2 = {"Geeks",
"for", "Geeks"};
// Printing vect2 elements
print(vect2);
// Modifying vect2
// push back string "is great"
vect2.push_back("is the great");
// Printing vect2 after modification
print(vect2);
int finalAnswer = 0;
for (auto x : vect1)
finalAnswer += x;
cout << "Final Answer: " <<
finalAnswer;
return 0;
}
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Using template so that this
// function works for all data
// types
template void print(
set& set1)
{
cout << "set " << ' ';
cout << '[' << ' ';
for (auto x : set1)
{
cout << x << ' ';
}
cout << ']';
cout << '\n';
}
// Driver code
int main()
{
// Declaring a set
set set1;
// Inserting elements in the set
for (int i = 0; i < 10; i++)
set1.insert(i);
// Printing set1 elements
print(set1);
// Declaring another set of
// string type
set set2;
// Inserting elements in the set
set2.insert("GeeksforGeeks");
// Printing set2 elements
print(set2);
int finalAnswer = 0;
for (auto x : set1)
finalAnswer += x;
cout << "Final Answer: " <<
finalAnswer;
return 0;
}
C++
//Template definition
template
//Function to print the variable
void print(T x)
{
// Using error stream to print
// the variable
cerr << x;
}
C++
// Template definition
template
// Function to print the elements
// of the vector
void print(vector& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// Same to print a variable (Function
// Overloading)
print(x);
cerr << ' ';
}
cerr << ']';
}
C++
//Template definition
template
// Function to print elements of the
// set arranged in non-descending order
void print(set& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// Same as printing a variable
// (Function Overloading)
print(x);
cerr << ' ';
}
cerr << ']';
}
C++
template
// Function to print the set elements
// arranged in non-ascending order
void print(set >& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// same as printing a variable
// (Function Overloading)
print(x);
cerr << ' ';
}
cerr << ']';
}
C++
// Template definition
template
// Function to print unordered
// set elements
void print(unordered_set& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// Same as printing a variable
// Using the concept of function
// overloading
print(x);
cerr << ' ';
}
cerr << ']';
}
C++
//Template definition
template
//Function to print map elements
// arranged in non-descending order
void print(map& a)
{
cerr << "[ ";
for (auto i : a)
{
// Same as variable using the
// concept of function overloading
print(i);
cerr << " ";
}
cerr << "]";
}
C++
//Template definition
template
//Function to print unordered map elements
void print(unordered_map& a)
{
cerr << "[ ";
for (auto i : a)
{
// Same as variable using the
// concept of function overloading
print(i);
cerr << " ";
}
cerr << "]";
}
C++
//Template definition
template
//Function to print multiset elements
// arranged in non-descending order
void print(multiset& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// Same as variable using the
// concept of function overloading
print(x);
cerr << ' ';
}
cerr << ']';
}
C++
//Template definition
template
//Function to print elements of a
// multiset arranged in non-ascending order
void print(multiset >& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// Same as variable using the
// concept of function overloading
print(x);
cerr << ' ';
}
cerr << ']';
}
C++
// Template definition
template
// Print function to print unordered
// set elements
void print(unordered_set& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// Same as variable using the
// concept of function overloading
print(x);
cerr << ' ';
}
cerr << ']';
}
C++
// Template definition
template
// Function to print vector of
// vectors elements
void print(vector >& a)
{
cerr << "[ ";
for (auto i : a)
{
// Same as variable using the
// concept of function overloading
print(i);
cerr << " ";
}
cerr << "]";
}
C++
// Template definition
template
// Function to print elements of a pair
void print(pair x)
{
// Sam as printing the variable using
// the concept of function overloading
print(x.ff);
cerr << ':';
// Same as variable using the concept
// of function overloading
print(x.ss);
}
C++
// Template definition
template
// Function to print vector of
// pairs elements
void print(vector >& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// Same as printing a variable using
// the concept of function overloading
print(x.ff);
cerr << ":";
// Same as printing a variable using
// the concept of function overloading
print(x.ss);
cerr << ' ';
}
cerr << ']';
}
C++
// We want to skip writing on error.txt
// file when online judge (Codechef,
// Codeforces, etc) is defined
#ifndef ONLINE_JUDGE
freopen("error.txt", "w", stderr);
// ONLINE_JUDGE
#endif
C++
// Now local function would look like:
void local()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
// ONLINE_JUDGE
#endif
// It basically means that these
// statements (Between ifndef and
// endif) would be skipped / ignored
// if ONLINE_JUDGE is defined We don't
// need to comment "local();" statement
// in our function while submitting our
// source code file to online judges.
// It would be handled automatically
#ifndef ONLINE_JUDGE
freopen("error.txt", "w", stderr);
// ONLINE_JUDGE
#endif
}
C++
// If online judge is defined
#ifndef ONLINE_JUDGE
#define debug(x)
cerr << #x << " ";
print(x);
cerr << '\n';
// If Online Judge is not defined
#else
#define debug(x)
#endif
C++
/* It is recommended below snippets in
your template file of competitive programming */
#include
using namespace std;
// Debugging Functions
templatevoid print(T x)
{
cerr << x;
}
template
void print(pair x)
{
print(x.ff);
cerr << ':';
print(x.ss);
}
template
void print(vector &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(set &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(set> &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(multiset &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(multiset> &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(unordered_set &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(vector> &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x.ff);
cerr << ":";
print(x.ss);
cerr << ' ';
}
cerr << ']';
}
template
void print(map &a)
{
cerr << "[ ";
for (auto i : a)
{
print(i);
cerr << " ";
}
cerr << "]";
}
template
void print(unordered_map &a)
{
cerr << "[ ";
for (auto i : a)
{
print(i);
cerr << " ";
}
cerr << "]";
}
template
void print(vector> &a)
{
cerr << "[ ";
for (auto i : a)
{
print(i);
cerr << " ";
}
cerr << "]";
}
void local()
{
// ONLINE_JUDGE
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
// ONLINE_JUDGE
#ifndef ONLINE_JUDGE
freopen("error.txt", "w", stderr);
#endif
#ifndef ONLINE_JUDGE
#define debug(x)
cerr << #x << " ";
print(x);
cerr << '\n';
#else
#define debug(x)
#endif
}
// Driver code
int main()
{
local();
// Number of elements in the vector
int n;
// Taking input from the user
// through input.txt file
cin >> n;
// Declaring a vector of integer
// type of size n
vector vect1(n);
// Initializing the vector
for(int i = 0 ; i < n ; i++)
cin >> vect1[i];
// Modifying the vector
for (auto& x : vect1)
{
if (x % 2 == 0)
x += 10;
else
x -= 10;
}
// Printing vect1 elements
// It will be printed in error.txt
// file using cerr stream
debug(vect1);
// Initializing a vector of string type
vector vect2 = {"Geeks", "for", "Geeks"};
// Printing vect2 elements
// It will be printed in error.txt
// file using cerr stream
debug(vect2);
// Modifying vect2
// push back string "is great"
vect2.push_back("is the great");
// Printing vect2 after modification
// It will be printed in error.txt
// file using cerr stream
debug(vect2);
// Calculating the answer
int finalAnswer = 0;
for (auto x : vect1)
finalAnswer += x;
// Finally, printing answer in output.txt
// file using cout stream
cout << "Final Answer: " << finalAnswer;
return 0;
}
C++
/* It is recommended below snippets in
your template file of competitive programming */
#include
using namespace std;
// Debugging Functions
templatevoid print(T x)
{
cerr << x;
}
template
void print(pair x)
{
print(x.ff);
cerr << ':';
print(x.ss);
}
template
void print(vector &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(set &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(set> &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(multiset &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(multiset> &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(unordered_set &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(vector> &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x.ff);
cerr << ":";
print(x.ss);
cerr << ' ';
}
cerr << ']';
}
template
void print(map &a)
{
cerr << "[ ";
for (auto i : a)
{
print(i);
cerr << " ";
}
cerr << "]";
}
template
void print(unordered_map &a)
{
cerr << "[ ";
for (auto i : a)
{
print(i);
cerr << " ";
}
cerr << "]";
}
template
void print(vector> &a)
{
cerr << "[ ";
for (auto i : a)
{
print(i);
cerr << " ";
}
cerr << "]";
}
void local()
{
// ONLINE_JUDGE
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
// ONLINE_JUDGE
#ifndef ONLINE_JUDGE
freopen("error.txt", "w", stderr);
#endif
#ifndef ONLINE_JUDGE
#define debug(x)
cerr << #x << " ";
print(x);
cerr << '\n';
#else
#define debug(x)
#endif
}
// Driver code
int main()
{
local();
// Number of elements in the set
int n;
// Taking input from the user
// through input.txt file
cin >> n;
// Declaring a set of integers
set set1;
for(int i = 0 ; i < n ; i++)
{
int number;
// Taking input from the user
// through input.txt file
cin >> number;
//Inserting in the set
set1.insert(number);
}
// Erasing from the set
if(!set1.empty())
{
// erasing the first element
// of the set
set1.erase(set1.begin());
}
// Printing set1 elements
// It will be printed in error.txt
// file using cerr stream
debug(set1);
// Declaring another set
set set2;
// Inserting in the set
set2.insert("GeeksforGeeks");
// Printing set2 elements
// It will be printed in error.txt file
// using cerr stream
debug(set2);
// Inserting in set
// Insert the string "is great"
set2.insert("Geek");
// Printing set2 elements after
// inserting into the set, It will
// be printed in error.txt file
// using cerr stream
debug(set2);
// Calculating the answer
int finalAnswer = 0;
for (auto x : set1)
finalAnswer += x;
// Finally, printing answer in output.txt
// file using cout stream
cout << "Final Answer: " << finalAnswer;
return 0;
}
第 3 步:从主函数:
// Call from the main function
local();
通过结合上述步骤,我们的完整程序将是:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Local function
void local()
{
#ifndef ONLINE_JUDGE
freopen("input.txt",
"r", stdin);
freopen("output.txt",
"w", stdout);
// ONLINE_JUDGE
#endif
}
// Driver code
int main()
{
local();
return 0;
}
第 4 步:现在 IDE 看起来与此类似:
使用打印函数调试:
每当我们需要打印变量或任何数据结构(如向量、集合、映射等)时,在我们的程序中创建一个打印函数。下面是实现相同方法的 C++ 程序:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Driver code
int main()
{
// Initializing a vector
vector vect = {2, 4, 10,
12, 17};
// First operation
for (auto& x : vect)
{
if (x % 2 == 0)
x += 10;
else
x -= 10;
}
// Second operation
for (auto& x : vect)
x += 2;
// Third operation
for (auto& x : vect)
x += 20;
}
假设我们的逻辑出现问题,因为在比赛期间没有获得所需的输出,因此检查向量的状态 在第一次操作之后,可以在接受向量的主函数之外创建一个打印函数。
C++
// print function outside the
// main function
void print(vector& vect)
{
cout << "vect " << ' ';
cout << '[' << ' ';
// Print vector elements
for (auto x : vect)
{
cout << x << ' ';
}
cout << ']';
}
每当需要检查向量元素时,可以调用 print() 函数 通过传递向量 作为 print函数的参数。
// Calling print function from main
print(vect);
下面是完整的 C++ 程序来说明如何实现上述概念:
C++
// C++ program to implement
// the above concept
#include
using namespace std;
// Print function for debugging
void print(vector& vect)
{
cout << "vect " << ' ';
cout << '[' << ' ';
// Print vector elements
for (auto x : vect)
{
cout << x << ' ';
}
cout << ']';
}
// Driver code
int main()
{
// Initializing a vector
vector vect = {2, 4, 10,
12, 17};
// First operation
for (auto& x : vect)
{
if (x % 2 == 0)
x += 10;
else
x -= 10;
}
// Printing vect elements after
// applying first operation
// Checking the status of vect as
// a part of debugging
print(vect);
// Second operation
for (auto& x : vect)
x += 2;
// Third operation
for (auto& x : vect)
x += 20;
int finalAnswer = 0;
for (auto x : vect)
finalAnswer += x;
// Print the final answer
cout << "\nFinal Answer: " <<
finalAnswer;
return 0;
}
vect [ 12 14 20 22 7 ]
Final Answer: 185
这种方法的缺点:
- 对于相同的数据结构但具有不同的数据类型,需要创建多个打印函数。比如有一个整数类型的向量和一个字符串类型的向量,那么为了打印元素,就需要在主函数之外创建两个打印函数。一个打印函数将接受整数类型的向量,而另一个打印函数将接受字符串类型的向量。
- 向量的内容将与所需的值一起打印在同一个 output.txt 文件中,这可能会让我们感到困惑。
- 需要注释用于调用的语句 从 main函数打印函数,最终将源代码文件提交给在线评委(Codeforces、Spoj、Codechef 等)。
使用模板调试:
在上述方法中,向量的数据类型是硬编码的。模板 可以在 C++ 中使用。模板是 C++ 中一个简单但功能强大的工具。简单的想法是将数据类型作为参数传递,这样就不需要为不同的数据类型编写相同的代码(打印函数)。下面是模板的 C++ 代码片段:
C++
// One print function works for
// all data types. This would work
// even for user defined types if
// operator '>' is overloaded
template
void print(vector vect)
{
// body
}
以下是说明上述概念的完整 C++ 程序:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Using template so that this
// function works for all data
// types
template void print(
vector& vect)
{
cout << "vect " << ' ';
cout << '[' << ' ';
for (auto x : vect)
{
cout << x << ' ';
}
cout << ']';
cout << '\n';
}
// Driver code
int main()
{
vector vect1 = {2, 4, 10,
12, 17};
for (auto& x : vect1)
{
if (x % 2 == 0)
x += 10;
else
x -= 10;
}
// Printing vect1 elements
print(vect1);
// Initializing a vector of
// string type
vector vect2 = {"Geeks",
"for", "Geeks"};
// Printing vect2 elements
print(vect2);
// Modifying vect2
// push back string "is great"
vect2.push_back("is the great");
// Printing vect2 after modification
print(vect2);
int finalAnswer = 0;
for (auto x : vect1)
finalAnswer += x;
cout << "Final Answer: " <<
finalAnswer;
return 0;
}
vect [ 12 14 20 22 7 ]
vect [ Geeks for Geeks ]
vect [ Geeks for Geeks is the great ]
Final Answer: 75
任何数据结构都可以做类似的事情,比如set 、 multiset 、 pairs等。下面是使用 set 的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Using template so that this
// function works for all data
// types
template void print(
set& set1)
{
cout << "set " << ' ';
cout << '[' << ' ';
for (auto x : set1)
{
cout << x << ' ';
}
cout << ']';
cout << '\n';
}
// Driver code
int main()
{
// Declaring a set
set set1;
// Inserting elements in the set
for (int i = 0; i < 10; i++)
set1.insert(i);
// Printing set1 elements
print(set1);
// Declaring another set of
// string type
set set2;
// Inserting elements in the set
set2.insert("GeeksforGeeks");
// Printing set2 elements
print(set2);
int finalAnswer = 0;
for (auto x : set1)
finalAnswer += x;
cout << "Final Answer: " <<
finalAnswer;
return 0;
}
set [ 0 1 2 3 4 5 6 7 8 9 ]
set [ GeeksforGeeks ]
Final Answer: 45
这种方法的缺点:
- 上面的方法效率不是很高,因为每次提交程序之前都需要在main里面注释print语句 函数。
- 数据结构的元素将与其他所需值一起打印在同一 output.txt 中 文件,这可能会让我们感到困惑。
使用 cerr 进行调试:
这个想法是使用cerr的组合 (错误流)和程序中的文件处理。创建一个单独的文件 (error.txt) 并使用 cerr 流而不是 cout 流。最后,借助文件处理,打印error.txt文件中数据结构的状态。
第 1 步:首先在 main函数之外添加以下代码段:
- 要打印变量,我们可以在函数:
C++
//Template definition
template
//Function to print the variable
void print(T x)
{
// Using error stream to print
// the variable
cerr << x;
}
- 要打印矢量元素,我们可以在函数:
C++
// Template definition
template
// Function to print the elements
// of the vector
void print(vector& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// Same to print a variable (Function
// Overloading)
print(x);
cerr << ' ';
}
cerr << ']';
}
- 要打印以非降序排列的集合元素,我们可以在函数:
C++
//Template definition
template
// Function to print elements of the
// set arranged in non-descending order
void print(set& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// Same as printing a variable
// (Function Overloading)
print(x);
cerr << ' ';
}
cerr << ']';
}
- 要打印以非升序排列的集合元素,我们可以在函数:
C++
template
// Function to print the set elements
// arranged in non-ascending order
void print(set >& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// same as printing a variable
// (Function Overloading)
print(x);
cerr << ' ';
}
cerr << ']';
}
- 打印无序集 元素,我们可以在函数:
C++
// Template definition
template
// Function to print unordered
// set elements
void print(unordered_set& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// Same as printing a variable
// Using the concept of function
// overloading
print(x);
cerr << ' ';
}
cerr << ']';
}
- 要打印地图元素,我们可以在函数:
C++
//Template definition
template
//Function to print map elements
// arranged in non-descending order
void print(map& a)
{
cerr << "[ ";
for (auto i : a)
{
// Same as variable using the
// concept of function overloading
print(i);
cerr << " ";
}
cerr << "]";
}
- 要打印无序的地图元素,我们可以在函数:
C++
//Template definition
template
//Function to print unordered map elements
void print(unordered_map& a)
{
cerr << "[ ";
for (auto i : a)
{
// Same as variable using the
// concept of function overloading
print(i);
cerr << " ";
}
cerr << "]";
}
- 要打印以非降序排列的多集元素,我们可以创建一个打印函数,其模板定义就在函数上方:
C++
//Template definition
template
//Function to print multiset elements
// arranged in non-descending order
void print(multiset& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// Same as variable using the
// concept of function overloading
print(x);
cerr << ' ';
}
cerr << ']';
}
- 要打印以非升序排列的多集元素,我们可以创建一个打印函数,其模板定义就在函数上方:
C++
//Template definition
template
//Function to print elements of a
// multiset arranged in non-ascending order
void print(multiset >& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// Same as variable using the
// concept of function overloading
print(x);
cerr << ' ';
}
cerr << ']';
}
- 要打印无序集合元素,我们可以在函数:
C++
// Template definition
template
// Print function to print unordered
// set elements
void print(unordered_set& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// Same as variable using the
// concept of function overloading
print(x);
cerr << ' ';
}
cerr << ']';
}
- 要打印向量元素的向量,我们可以在函数:
C++
// Template definition
template
// Function to print vector of
// vectors elements
void print(vector >& a)
{
cerr << "[ ";
for (auto i : a)
{
// Same as variable using the
// concept of function overloading
print(i);
cerr << " ";
}
cerr << "]";
}
- 打印一对 元素,我们可以在函数:
C++
// Template definition
template
// Function to print elements of a pair
void print(pair x)
{
// Sam as printing the variable using
// the concept of function overloading
print(x.ff);
cerr << ':';
// Same as variable using the concept
// of function overloading
print(x.ss);
}
- 打印一对向量 元素,我们可以在函数:
C++
// Template definition
template
// Function to print vector of
// pairs elements
void print(vector >& a)
{
cerr << '[' << ' ';
for (auto x : a)
{
// Same as printing a variable using
// the concept of function overloading
print(x.ff);
cerr << ":";
// Same as printing a variable using
// the concept of function overloading
print(x.ss);
cerr << ' ';
}
cerr << ']';
}
第 2 步:再创建一个新文件 ( error.txt ) 并确保它在同一个文件夹中。
error.txt file: All the elements of the data structures that we have mentioned in the above snippets would be printed in this text file only without affecting the output.txt file.
Note that we want to write in this file using error stream (cerr). Again help from ifndef and endif preprocessor directives can be taken.
C++
// We want to skip writing on error.txt
// file when online judge (Codechef,
// Codeforces, etc) is defined
#ifndef ONLINE_JUDGE
freopen("error.txt", "w", stderr);
// ONLINE_JUDGE
#endif
在我们的本地函数中加入以上几行之后,完整的函数就变成了:
C++
// Now local function would look like:
void local()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
// ONLINE_JUDGE
#endif
// It basically means that these
// statements (Between ifndef and
// endif) would be skipped / ignored
// if ONLINE_JUDGE is defined We don't
// need to comment "local();" statement
// in our function while submitting our
// source code file to online judges.
// It would be handled automatically
#ifndef ONLINE_JUDGE
freopen("error.txt", "w", stderr);
// ONLINE_JUDGE
#endif
}
第 3 步:另外,我们不想评论 debug(data_structure) 提交源代码时的语句 提交给在线评委。简而言之,需要找到一种方法,以便 调试 函数将适用于 sublime text (IDE),但对于在线评委,它们将被跳过/忽略。
同样,这可以通过在源代码中再次使用 ifndef 和 endif 预处理器指令来实现。
C++
// If online judge is defined
#ifndef ONLINE_JUDGE
#define debug(x)
cerr << #x << " ";
print(x);
cerr << '\n';
// If Online Judge is not defined
#else
#define debug(x)
#endif
现在 IDE 看起来与此类似:
第 4 步:当需要检查任何数据结构的状态时,可以进行以下调用:
// Calling from the main function
debug(dataStructure);
第5步:下面是上述方法的实现:
示例 1:
C++
/* It is recommended below snippets in
your template file of competitive programming */
#include
using namespace std;
// Debugging Functions
templatevoid print(T x)
{
cerr << x;
}
template
void print(pair x)
{
print(x.ff);
cerr << ':';
print(x.ss);
}
template
void print(vector &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(set &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(set> &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(multiset &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(multiset> &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(unordered_set &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(vector> &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x.ff);
cerr << ":";
print(x.ss);
cerr << ' ';
}
cerr << ']';
}
template
void print(map &a)
{
cerr << "[ ";
for (auto i : a)
{
print(i);
cerr << " ";
}
cerr << "]";
}
template
void print(unordered_map &a)
{
cerr << "[ ";
for (auto i : a)
{
print(i);
cerr << " ";
}
cerr << "]";
}
template
void print(vector> &a)
{
cerr << "[ ";
for (auto i : a)
{
print(i);
cerr << " ";
}
cerr << "]";
}
void local()
{
// ONLINE_JUDGE
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
// ONLINE_JUDGE
#ifndef ONLINE_JUDGE
freopen("error.txt", "w", stderr);
#endif
#ifndef ONLINE_JUDGE
#define debug(x)
cerr << #x << " ";
print(x);
cerr << '\n';
#else
#define debug(x)
#endif
}
// Driver code
int main()
{
local();
// Number of elements in the vector
int n;
// Taking input from the user
// through input.txt file
cin >> n;
// Declaring a vector of integer
// type of size n
vector vect1(n);
// Initializing the vector
for(int i = 0 ; i < n ; i++)
cin >> vect1[i];
// Modifying the vector
for (auto& x : vect1)
{
if (x % 2 == 0)
x += 10;
else
x -= 10;
}
// Printing vect1 elements
// It will be printed in error.txt
// file using cerr stream
debug(vect1);
// Initializing a vector of string type
vector vect2 = {"Geeks", "for", "Geeks"};
// Printing vect2 elements
// It will be printed in error.txt
// file using cerr stream
debug(vect2);
// Modifying vect2
// push back string "is great"
vect2.push_back("is the great");
// Printing vect2 after modification
// It will be printed in error.txt
// file using cerr stream
debug(vect2);
// Calculating the answer
int finalAnswer = 0;
for (auto x : vect1)
finalAnswer += x;
// Finally, printing answer in output.txt
// file using cout stream
cout << "Final Answer: " << finalAnswer;
return 0;
}
文件.cpp 文件:
输入.txt 文件
输出.txt 文件
错误.txt 文件
示例 2:
C++
/* It is recommended below snippets in
your template file of competitive programming */
#include
using namespace std;
// Debugging Functions
templatevoid print(T x)
{
cerr << x;
}
template
void print(pair x)
{
print(x.ff);
cerr << ':';
print(x.ss);
}
template
void print(vector &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(set &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(set> &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(multiset &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(multiset> &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(unordered_set &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x);
cerr << ' ';
}
cerr << ']';
}
template
void print(vector> &a)
{
cerr << '[' << ' ';
for(auto x : a)
{
print(x.ff);
cerr << ":";
print(x.ss);
cerr << ' ';
}
cerr << ']';
}
template
void print(map &a)
{
cerr << "[ ";
for (auto i : a)
{
print(i);
cerr << " ";
}
cerr << "]";
}
template
void print(unordered_map &a)
{
cerr << "[ ";
for (auto i : a)
{
print(i);
cerr << " ";
}
cerr << "]";
}
template
void print(vector> &a)
{
cerr << "[ ";
for (auto i : a)
{
print(i);
cerr << " ";
}
cerr << "]";
}
void local()
{
// ONLINE_JUDGE
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
// ONLINE_JUDGE
#ifndef ONLINE_JUDGE
freopen("error.txt", "w", stderr);
#endif
#ifndef ONLINE_JUDGE
#define debug(x)
cerr << #x << " ";
print(x);
cerr << '\n';
#else
#define debug(x)
#endif
}
// Driver code
int main()
{
local();
// Number of elements in the set
int n;
// Taking input from the user
// through input.txt file
cin >> n;
// Declaring a set of integers
set set1;
for(int i = 0 ; i < n ; i++)
{
int number;
// Taking input from the user
// through input.txt file
cin >> number;
//Inserting in the set
set1.insert(number);
}
// Erasing from the set
if(!set1.empty())
{
// erasing the first element
// of the set
set1.erase(set1.begin());
}
// Printing set1 elements
// It will be printed in error.txt
// file using cerr stream
debug(set1);
// Declaring another set
set set2;
// Inserting in the set
set2.insert("GeeksforGeeks");
// Printing set2 elements
// It will be printed in error.txt file
// using cerr stream
debug(set2);
// Inserting in set
// Insert the string "is great"
set2.insert("Geek");
// Printing set2 elements after
// inserting into the set, It will
// be printed in error.txt file
// using cerr stream
debug(set2);
// Calculating the answer
int finalAnswer = 0;
for (auto x : set1)
finalAnswer += x;
// Finally, printing answer in output.txt
// file using cout stream
cout << "Final Answer: " << finalAnswer;
return 0;
}
文件.cpp 文件:
输入.txt 文件
输出.txt 文件
错误.txt 文件
这种调试方法的优点:
- 现在在将源代码文件提交给在线评委之前,无需对程序中的每条调试语句进行注释。
- 数据结构或 STL 元素将打印在单独的文件 (error.txt) 中 并且所需的输出值将打印在 output.txt 文件中,使其更具可读性。
- 简而言之,这可以在编码比赛中节省大量时间。