1.
std::search
是C++中的一个函数,用于在两个迭代器指定的范围内搜索子序列。它是C++标准库的<algorithm>
头文件的一部分template< class ForwardIterator1, class ForwardIterator2 >
ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2);
first1
,last1
:输入迭代器定义搜索范围。first2
,last2
:定义要搜索的元素范围的输入迭代器。[first2, last2)
内子序列[first1, last1)
第一次出现的第一个元素。last1
。(即搜索范围的最后一个值)#include <iostream>
#include <algorithm>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<int> subseq = {4, 5, 6};
auto result = std::search(vec.begin(), vec.end(), subseq.begin(), subseq.end());
if (result != vec.end()) {
std::cout << "Subsequence found at position: " << std::distance(vec.begin(), result) << std::endl;
} else {
std::cout << "Subsequence not found." << std::endl;
}
return 0;
}
2.
std::find
是 C++ 标准库中的一个函数,std::vector
, std::list
, std::array
等)或者数组中查找特定值的位置。template< class InputIt, class T >
InputIt find( InputIt first, InputIt last, const T& value );
first
和 last
是表示要搜索范围的迭代器。first
表示要搜索的起始位置,而 last
表示要搜索的结束位置(不包括 last
自身)。value
是要查找的特定值。1.std::find
函数的返回值是一个迭代器,std::find
将返回指向范围末尾的迭代器(即 last
参数所指向的位置)。#include <iostream>
#include <algorithm>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 在向量中查找值为 3 的元素
auto it = std::find(vec.begin(), vec.end(), 3);
if (it != vec.end()) {
std::cout << "Found value 3 at index: " << std::distance(vec.begin(), it) << std::endl;
} else {
std::cout << "Value 3 not found in the vector." << std::endl;
}
return 0;
}
throw std::invalid_argument
时,[capture clause](parameters) -> return_type {
// Lambda body (function implementation)
// It can use captured variables, take parameters, and return a value
// e.g., return some_value;
};
capture clause
:用于捕获外部变量的列表,可以为空或包含变量。parameters
:lambda 函数的参数列表,类似于普通函return_type
:lambda 函数的返回类型。可以省略(由编译器推断)或使用 auto
关键字。#include <iostream>
int main() {
// Lambda 表达式示例:一个接受两个参数并返回它们的和的函数
auto sum = [](int a, int b) { return a + b; };
// 使用 Lambda 表达式计算并输出结果
int result = sum(5, 3);
std::cout << "Sum: " << result << std::endl;
return 0;
}
[ ]
来获取外部变量取决于你在 Lambda 函数体内是否需要使用值捕获 [=]
:
[=]
捕获所有外部变量。引用捕获 [&]
:
[&]
引用所有特定变量捕获 [var1, var2]
:
[var1, &var2]
值捕获 var1
,引用捕获 `var2
。int x = 5;
auto lambda_without_capture = []() {
// Lambda 函数体内未使用外部变量,无需捕获
return 42;
};
auto lambda_with_capture = [=]() {
// 在 Lambda 函数体内使用了外部变量 x,需要值捕获
return x + 10;
};
auto lambda_with_reference_capture = [&]() {
// 在 Lambda 函数体内使用了外部变量 x,需要引用捕获
x = 100; // 修改了外部变量 x 的值
return x + 10;
};
std::all_of
是C++标准库提供的一个算法。它对由范围定义的元素序列进行操作template <class InputIt, class UnaryPredicate>
bool all_of(InputIt first, InputIt last, UnaryPredicate p);
first
,last
:定义要检查的范围的迭代器。p
:一元谓词函数或函数对象,定义要检查的条件std::all_of
对于要检查的范围的迭代器中的所有元素都是由一元函数p
指定的条件是否true
true
,否则返回false
。first == last
),则函数返回`trshi
#include <algorithm>
#include <vector>
bool isOdd(int num) {
return num % 2 != 0;
}
int main() {
std::vector<int> numbers = {1, 3, 5, 7, 9};
// Check if all elements in the vector are odd using a lambda function
bool allAreOdd = std::all_of(numbers.begin(), numbers.end(), [](int n) { return n % 2 != 0; });
// Alternatively, using a named function
bool allAreOdd2 = std::all_of(numbers.begin(), numbers.end(), isOdd);
return 0;
}
#include <iostream>
#include <algorithm>
#include <unordered_set>
#include <stdexcept>
#include <unordered_map>
#include "wikiscraper.h"
#include "error.h"
using std::cout; using std::endl;
using std::cerr; using std::string;
using std::unordered_map; using std::unordered_set;
/*
* You should delete the code in this function and
* fill it in with your code from part A of the assignment.
*
* If you used any helper functions, just put them above this function.
*/
// TODO: ASSIGNMENT 2 TASK 4:
// Please implement a function that can determine if a wiki link is valid or not.
// As a reminder, it needs to take in a string and return whether or not
// # or : is contained in the string.
// Estimated length: ~5-10 lines
///
// BEGIN STUDENT CODE HERE
bool valid_wikilink(const string& link) {
// replace these lines!
return std::all_of(link.begin(),link.end(),[](const auto & item){
if(item== '#' || item == ':'){
return false;}
return true;
});
}
// END STUDENT CODE HERE
///
unordered_set<string> findWikiLinks(const string& inp) {
/* Delimiter for start of a link */
static const string delim = "href=\"/wiki/";
unordered_set<string> ret;
auto url_start = inp.begin();
auto end = inp.end();
while(true) {
// TODO: ASSIGNMENT 2 TASK 1:
// Set url_start to the next location of "delim" (starting your search at url_start), using std::search.
// After doing so, break out of the while loop if there are no occurrences of delim left
// (use your work from the line above).
// Estimated length: 2-3 lines
///
// BEGIN STUDENT CODE HERE
// 利用std::search查找url中是否包含delim
// 包含即返回搜索范围最后一个元素
url_start =std::search(url_start,end,delim.begin(),delim.end());
if (url_start == end)
//它会抛出一个带有消息“Not implemented yet.\n”的std::invalid_argument异常
break;
// END STUDENT CODE HERE
///
// TODO: ASSIGNMENT 2 TASK 2:
// Set url_end to the end of the wikilink. Start searching after the delimeter you found above.
// Make sure to use std::find! (std::find looks for a single element in a container, e.g. character in
// a string—std::search looks for a series of elements in a container, like a substring in a string.
// remember that a string is represented as an array of characters, and is also a container!)
// Estimated length: 1 lines
///
auto url_end = std::find(url_start+delim.length(),end,'\"');
// END STUDENT CODE HERE
///
// TODO: ASSIGNMENT 2 TASK 3:
// Last exercise of this function! Create a string from the two iterators (url_start and url_end) above
// using a string constructor. Make sure you start the string AFTER the delimiter you found in task 5!
// Estimated length: 1 lines
///
// BEGIN STUDENT CODE HERE (delete/edit this line)
string link;
link.assign(url_start+delim.length(),url_end);
// END STUDENT CODE HERE
///
/*
* Only add link to the set if it is valid i.e. doesn't
* contain a ':' or a '#'.
*/
if(valid_wikilink(link)){
ret.insert(link);
}
url_start = url_end;
}
return ret;
}
/*
* ==================================================================================
* | Don't edit anything below here, but take a peek! |
* ==================================================================================
*/
unordered_set<string> WikiScraper::getLinkSet(const string& page_name) {
if(linkset_cache.find(page_name) == linkset_cache.end()) {
auto links = findWikiLinks(getPageSource(page_name));
linkset_cache[page_name] = links;
}
return linkset_cache[page_name];
}
WikiScraper::WikiScraper() {
(void)getPageSource("Main_Page");
}
string createPageUrl(const string& page_name) {
return "https://en.wikipedia.org/wiki/" + page_name;
}
void notFoundError(const string& msg, const string& page_name, const string& url) {
const string title = " AN ERROR OCCURED DURING EXECUTION. ";
const string border(title.size() + 4, '*');
cerr << endl;
errorPrint(border);
errorPrint("* " + title + " *");
errorPrint(border);
errorPrint();
errorPrint("Reason: " + msg);
errorPrint();
errorPrint("Debug Information:");
errorPrint();
errorPrint("\t- Input parameter: " + page_name);
errorPrint("\t- Attempted url: " + url);
errorPrint();
}
string WikiScraper::getPageSource(const string &page_name) {
const static string not_found = "Wikipedia does not have an article with this exact name.";
if(page_cache.find(page_name) == page_cache.end()) {
string url = createPageUrl(page_name);
// using the cpr library to get the HTML content of a webpage!
// we do so by aking a GET REST request to a wikipedia webpage, which
// returns the content of the webpage. when this assignment was on QtCreator,
// we had a whole separate assignment for making sure an alternate Internet Library
// (not cpr) was working on your personal pc. look how simple it is now!
cpr::Response r = cpr::Get(cpr::Url{url});
string ret = r.text;
if (r.status_code != 200) {
notFoundError("Couldn't get page source. Have you entered a valid link?", page_name, url);
return "";
}
if(std::search(ret.begin(), ret.end(), not_found.begin(), not_found.end()) != ret.end()){
notFoundError("Page does not exist!", page_name, url);
return "";
}
size_t indx = ret.find("plainlinks hlist navbar mini");
if(indx != string::npos) {
return ret.substr(0, indx);
}
page_cache[page_name] = ret;
}
return page_cache[page_name];
}
Running test: ./build/test 1
Running test: ./build/test 2
Running test: ./build/test 3
Running test: ./build/test 4
Running test: ./build/test 5
Running test: ./build/test 6
Running test: ./build/test 7
Running test: ./build/test 8
All 8 tests passed!