【问题标题】:How to initialize a map of char to char with null values in c++?如何在 C++ 中使用空值初始化 char 到 char 的映射?
【发布时间】:2021-02-09 17:26:35
【问题描述】:

我正在尝试将每个节点的父节点存储在无序映射中,我需要使用 NULL 初始化值,如下所示:

//This is inside a method of a template class
std::unordered_map<T, T> parent;
parent[start] = NULL;

这会引发警告:

warning: converting to non-pointer type 'std::unordered_map<char, char, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, char> > >::mapped_type' {aka 'char'} from NULL [-Wconversion-null]
      parent[start] = NULL;

这在 T 是 char 时有效,但不适用于其他类型。

//This is inside a method of a template class
std::unordered_map<T, T> parent;
parent[start] = '\0';

如何使我可以将键的值存储为 NULL。 P.S:我是 C++ 新手。

T curr = end; // Here end is variable passed by user
 while(curr != NULL) { // I want to check whether current is NULL
 res.push(curr); // res is a stack, and I push the element(value of key)to it
 curr = parent[curr];
}

我想检查一个 NULL 值并停止 while 循环。

这是该方法的完整代码:

#include<iostream>
#include<vector>
#include<algorithm>
#include<unordered_map>
#include<list>
#include<queue>
#include <climits>
#include <stack>
#include <string>
using namespace std;

template <typename T>
class TemplateGraph {

  private:
    int V;
    unordered_map<T, list<pair<T, int>>> adjList;
    
  public:
    TemplateGraph(int v): V(v) {}
    void addEdge(T from, T to,bool isBiDir, int weight) {
      adjList[from].push_back(make_pair(to, weight));
      if(isBiDir) {
        adjList[to].push_back(make_pair(from, weight));
      }
    }
   void getPath(T start, T end) {
      unordered_map<T, int> dist;
      priority_queue<pair<T, int>, vector<pair<T, int>>, greater<pair<T, int>>> pq;
      unordered_map<T, T> parent;
      stack<T> res;
// adjList is of type =
// unordered_map<T, list<pair<T, int>>> adjList;
      for(auto vtx: adjList) { 
        T key = vtx.first;
        dist[key] = INT_MAX;
      }
      pq.push(make_pair(start, 0));
      dist[start] = 0;
      parent[start] = 0;
      while(!pq.empty()){
        T top = pq.top().first;
        pq.pop();
        for(auto nbr: adjList[top]){
          T node = nbr.first;
          int wt = nbr.second;
          int newWt = dist[top] + wt;
          if(newWt < dist[node]) {
            dist[node] = newWt;
            pq.push(make_pair(node, dist[node]));
            parent[node] = top;
          }
        }
      }
      T curr = end;
      while(curr != 0) {
        res.push(curr);
        curr = parent[curr];
      }
      while(!res.empty()){
        T node = res.top();
        res.pop();
        cout << node << " ";
      } 
    }
}

int main(){
  TemplateGraph<char> g2(9);
  g2.addEdge('A', 'B', true, 2);
  g2.addEdge('A', 'C', true, 5);
  g2.addEdge('B', 'D', true, 7);
  g2.addEdge('C', 'D', true, 2);
  g2.addEdge('C', 'E', true, 3);
  g2.addEdge('E', 'F', true, 4);
  g2.addEdge('E', 'H', true, 3);
  g2.addEdge('F', 'G', true, 1);
  g2.addEdge('D', 'F', true, 1);
  g2.getPath('A', 'F');
  TemplateGraph<int> g(9);
  g.addEdge(1, 2, true, 4);
  g.addEdge(4, 1, true, 3);
  g.addEdge(2, 3, true, 2);
  g.addEdge(2, 5, true, 4);
  g.addEdge(4, 5, true, 1);
  g.addEdge(3, 8, true, 5);
  g.addEdge(3, 7, true, 2);
  g.addEdge(7, 9, true, 1);
  g.getPath(1, 5);
  return 0;
}

【问题讨论】:

  • chars 没有空值。但是,它们的值可以为零。你对NULL 有什么期望? “如何使我可以将键的值存储为 NULL” - 看起来您将值设置为 NULL - 而不是键。
  • 您是否只想根据T 插入'\0'nullptr00.0 之类的“默认值”?也许您还想做一些std::optional 可以帮助您的事情。更多代码可能有助于澄清。
  • 我想将第一个键初始化为 NULL,并在循环中为每个节点添加父节点。我需要 NULL 作为第一个键,以便在通过跟随其父节点遍历节点时进行范围检查。有点像我们在 Dijkstra 算法中所做的
  • 我会建议一种不同的策略 - 根本不要尝试在地图中放置 NULL 值。仅添加具有要分配的实际值的键。您可以使用映射的find() 方法来确定映射中是否存在给定的键,并仅在它确实存在时获取它的迭代器。
  • @RemyLebeau 谢谢!!!现在工作正常...

标签: c++ dictionary data-structures


【解决方案1】:

C++ 没有“空值”的概念。所有整数都有整数值,所有字符都有 char 值,所有字符串都有字符串值,所有指针都有指针值。总是。现在,您可能有一个值对待为空,例如nullptr 用于指针,'\0' 用于字符,0 用于整数,但变量仍然存在作为一个值。

您通常可以使用{} 来获取任何类型的默认值,如果您愿意,可以将其视为神奇的“无价值”。或者,您可以使用std::optional&lt;T&gt;,除了T 的任何有效值之外,它还可以具有std::nullopt 的值。

【讨论】:

  • "C++ 没有“空值”的概念" - 实际上,通过std::optional
【解决方案2】:

'\0' 是 char 类型。 NULL 是 void * 类型的宏

你可以使用'\0'或者你可以存储一个字符指针而不是字符。例如 char*

【讨论】:

  • From cppreference: "在 C 中,宏 NULL 的类型可能为 void*,但在 C++ 中是不允许的"
  • 感谢您的回复,当 T 为 char 时,'/0' 工作正常。但是它不适用于 int 和 string(如预期的那样)。我正在使用模板,所以我需要一个适用于所有模板的解决方案,即 int、char 和 string。有什么方法可以让地图同时接受 T 和 NULL?
  • 我想将第一个键初始化为 NULL,并在循环中为每个节点添加父节点。我需要 NULL 作为第一个键,以便在通过跟随其父节点遍历节点时进行范围检查。有点像我们在 Dijkstra 算法中所做的。
  • 那如何初始化一个空值的变量呢?有什么办法吗?我来自JS背景。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-15
  • 1970-01-01
  • 2023-03-17
  • 2012-07-27
  • 2017-05-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多