我有一些代码: 我需要删除重复项,我真的不知道哪个步骤出错了。 有点失去了睡眠。 我觉得我已经不必要地过度复杂了,但是脑子里已经死了,看看我哪里出错了。
仍有问题=(
我正在根据建议进行改变...即使我的arr大小为8,仍然会跑出界限... 我已经尝试过打印值,它似乎在第3个元素上出乎意料地突破但我不知道该怎么做。任何其他帮助将不胜感激...
template <typename T>
void removeDup(std::vector<T> & v)
{
int last = v.size()-1;
for(int i = 0; i <= v.size(); i++)
{
if (count(v, i, last, v[i]) > 1){ // if there is more than 1
v.erase(v.begin()+(i)); // erase it
}
}
}
template <typename T>
int count(const std::vector<T> & v, int first, int last, const T& target){
int index = first;
int count = 0;
for (index; index < last; index++){
if (v[index] == target){
count++;
}
}
return count;
}
template <typename T>
int seqVectSearch(const std::vector<T> & v, int first, int last, const T& target){
int index = first;
int returnVal = -1;
for (index; index < last; index++){
if (v[index] == target){
returnVal = index;
}
}
return returnVal;
}
template <typename T>
void writeVector(const std::vector<T> & v){
int i;
int n = v.size();
for (i = 0; i < n; i++)
std::cout << v[i] << ' ';
std::cout << std::endl;
}
template void removeDup(std::vector<int> & v);
template int seqVectSearch(const std::vector<int> & v, int first, int last, const int& target);
template void writeVector(const std::vector<int> & v);
template int count(const std::vector<int> & v, int first, int last, const int& target);
输出:
Testing removeDup
Original vector is 1 7 2 7 9 1 2 8 9
Vector with duplicates removed is 1 2 7 9 1 2 8 9
1 2 7 9 1 2 8 9
Press any key to continue . . .
答案 0 :(得分:1)
如果您删除某个项目,则需要测试下一个项目
保持你刚刚测试的位置,所以更新
在这种情况下索引是不对的。
erase
返回一个迭代器,如果你愿意,它可以很方便
迭代并有条件地删除一些项目
另请注意count
中已定义<algorithm>
,
你不需要定义自己的。
template <typename T>
void removeDup(std::vector<T>& v)
{
auto iter = v.begin()
while( iter != v.end() )
{
if( std::count(iter, v.end(), *iter) > 1)
iter = v.erase(iter);
else
++iter;
}
}
然而,请注意,这会改变很多物品,
并且erase-remove idiom可能更适合。
答案 1 :(得分:1)
这是一个稳定的解决方案(保留元素的相对顺序),使用C ++标准模板库中的std::remove_if()
。正如您所看到的,实际删除重复项只需要大约10行实际代码;其余的(遗憾的是)C ++噪音包含文件和“漂亮”打印容器到stdout。
核心思想是保留一组已经在谓词中看到的元素;如果元素是重复的(即可以删除),则谓词是返回true
的仿函数,否则返回false
。
复杂性应该是O(n)+ O(n log n) - 每个元素需要检查一次,set
中的查找是O(n log n)。
#include <set>
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
template <typename T>
struct remove_dups_predicate {
typedef std::set<T> unique_values_t;
// Return true if we've seen this element before
// note that set.insert(...) returns pair<iterator,bool>
// with the bool telling wether or not the element was
// succesfully inserted, i.e. it should *not* be removed
bool operator()(const T& element) {
return !unique_values_seen.insert(element).second;
}
unique_values_t unique_values_seen;
};
int main( void ) {
std::vector<int> vi{ 1, 7, 2, 7, 9, 1, 2, 8, 9};
std::cout << "Before: ";
std::copy(vi.begin(), vi.end(), std::ostream_iterator<int>(std::cout, ", "));
std::cout << std::endl;
// Remove the duplicates
std::vector<int>::iterator it = std::remove_if(vi.begin(), vi.end(),
remove_dups_predicate<int>());
// print to stdout
std::cout << "After: ";
std::copy(vi.begin(), it, std::ostream_iterator<int>(std::cout, ", "));
std::cout << std::endl;
return 0;
}
运行此项作为输出:
Before: 1, 7, 2, 7, 9, 1, 2, 8, 9,
After: 1, 7, 2, 9, 8,
答案 2 :(得分:-1)
关于算法存在一些错误。主要是范围问题。
v.erase(v.begin()+(i-1));
您的i
变量从0开始,因此您不需要删除之前的元素。只需删除begin()+i
。
count(v, i, last, i)
您已通过last
count(...)
size()-1
index <= last
的价值。因此,您的迭代必须等到index < last
,而不仅仅是i
。
另一个问题,第四个参数不是v[i]
,是template <typename T>
void removeDup(std::vector<T> & v) {
for(int i = 0; i <= v.size(); i++)
{
if (count(v, i, v[i]) > 1){ // if there is more than 1
v.erase(v.begin()+i); // erase it
i--; // Decrement to stay at the same index.
}
}
}
template <typename T>
int count(const std::vector<T> & v, int first, const T& target){
int count = 0;
for (int index = first; index < v.size(); index++){
if (v[index] == target){
count++;
}
}
return count;
}
。您的代码只能编译,因为您正在使用整数向量进行测试,这是一种相同类型的索引。
它可能有其他错误,请仔细查看算法和索引范围。一个好的选择是打印功能的每一步。
这是两个核心方法的代码。如果您想在其他任务中使用类似的东西,请复制逻辑。
extension WKWebView {
private struct key {
static let scale = unsafeBitCast(Selector("scalesPageToFit"), UnsafePointer<Void>.self)
}
private var sourceOfUserScript: String {
return "(function(){\n" +
" var head = document.getElementsByTagName('head')[0];\n" +
" var nodes = head.getElementsByTagName('meta');\n" +
" var i, meta;\n" +
" for (i = 0; i < nodes.length; ++i) {\n" +
" meta = nodes.item(i);\n" +
" if (meta.getAttribute('name') == 'viewport') break;\n" +
" }\n" +
" if (i == nodes.length) {\n" +
" meta = document.createElement('meta');\n" +
" meta.setAttribute('name', 'viewport');\n" +
" head.appendChild(meta);\n" +
" } else {\n" +
" meta.setAttribute('backup', meta.getAttribute('content'));\n" +
" }\n" +
" meta.setAttribute('content', 'width=device-width, user-scalable=no');\n" +
"})();\n"
}
var scalesPageToFit: Bool {
get {
return objc_getAssociatedObject(self, key.scale) != nil
}
set {
if newValue {
if objc_getAssociatedObject(self, key.scale) != nil {
return
}
let time = WKUserScriptInjectionTime.AtDocumentEnd
let script = WKUserScript(source: sourceOfUserScript, injectionTime: time, forMainFrameOnly: true)
configuration.userContentController.addUserScript(script)
objc_setAssociatedObject(self, key.scale, script, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
if URL != nil {
evaluateJavaScript(sourceOfUserScript, completionHandler: nil)
}
} else if let script = objc_getAssociatedObject(self, key.scale) as? WKUserScript {
objc_setAssociatedObject(self, key.scale, nil, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
configuration.userContentController.removeUserScript(script)
if URL != nil {
let source = "(function(){\n" +
" var head = document.getElementsByTagName('head')[0];\n" +
" var nodes = head.getElementsByTagName('meta');\n" +
" for (var i = 0; i < nodes.length; ++i) {\n" +
" var meta = nodes.item(i);\n" +
" if (meta.getAttribute('name') == 'viewport' && meta.hasAttribute('backup')) {\n" +
" meta.setAttribute('content', meta.getAttribute('backup'));\n" +
" meta.removeAttribute('backup');\n" +
" }\n" +
" }\n" +
"})();"
evaluateJavaScript(source, completionHandler: nil)
}
}
}
}
}
extension WKUserContentController {
public func removeUserScript(script: WKUserScript) {
let scripts = userScripts
removeAllUserScripts()
scripts.forEach {
if $0 != script { self.addUserScript($0) }
}
}
}