1

我需要向报价服务器发送请求。每个请求都应该有一个独特的请求编号(无符号整数),以便在返回带有附加请求编号的报价时,我会知道这些报价属于哪个符号。这种情况有什么特殊的字符编码吗?例如,“A”是 13,“B”是 14,所以对于“BA”符号,我的请求编号将是 1413。

4

4 回答 4

3

As for mapping the chars directly to a uint, can you guarantee that the symbols are 6 characters or fewer? If not, then there are more possible symbol values than possible uint values.

In any event, the point of a request number is not to encode information about the request; rather, you should keep a dictionary of request numbers (as keys) and information about what to do with the response (as values). With your approach, if you have more than one request for the same symbol, you would end up with different requests that share the same request number.

For example, if you want to map the response to a symbol, you could do this:

private Dictionary<uint, string> _requests = new Dictionary<int, string>();
private uint _requestNumber = 0;

void SendRequest(string symbol)
{
    uint currentRequestNumber = _requestNumber++;
    _requests[currentRequestNumber] = symbol;
    //... send request using currentRequestNumber
}

void ReceiveResponse(Response response)
{
    string symbol = _requests[response.RequestNumber];
    _requests.Remove(response.RequestNumber);
    //...do something with the response...
}

This is not thread safe; it's just a sketch to illustrate the idea.

To answer the question as asked, if the range of possible symbol values is small enough, you could take the approach you outline in your question, where each character maps to a 2-digit number, and you simply concatenate these numbers. I'm not aware of an existing system that uses this approach.

This approach wastes many uint values that cannot correspond to any symbol. For example, if A is 10, and Z is 35, and \ is 36, then these ranges are wasted: 0 to 9, 37-1009, 1037-1109, etc.

Another option would be to interpret the symbol as a base-27 number (with 'A' to 'Z' plus '\' as valid digits) and convert it to base 10.

If you would like some sample code, please give some more information about the range of possible symbol values.

于 2012-04-03T21:27:49.427 回答
2

字符总是大写AZ吗?如果是这样,像这样简单的东西将以您描述的方式转换它:

var symbol = "BA";
var encoded = symbol.Aggregate(0u, (acc, c) => (uint)(acc * 100 + c - 'A' + 13));
于 2012-04-03T21:24:39.373 回答
1

Assuming A = 13, B = 14, ..., Z = 38

you can write a simple function that does this conversion for you. Something like:

uint output = 0;
foreach (char c in inpStr) {
    output = output * 100 + (13 + c - 'A');
}
return output;

Where inpStr = "BA" in your example.

于 2012-04-03T21:28:07.037 回答
1

If your symbols are always upper case letters, you can create a mapping something like this:

uint result = 0;
uint power = 1;

for (int i=0; i < input.Length; i++)
{
  uint digitValue = power * (input[i] - 'A');
  result += digitValue;
  power *= 26;
}

This effectively considers your symbol to be a base-26 number (digits are 'A' through 'Z') and converts it to base-10, with the "ones" digit furthest to the left (reverse of standard numbers, but irrelevant because it's internally consistent). If you wanted to treat the digits as ones-digit-on-the-left, you would just need to modify input[i] to be input[input.Length - i].

Update Given your clarification that the '/' symbol is also allowed, just convert the "base" from 26 to 27 and order "/" just above "Z" (arbitrary, but easier). You will need to test if input[i] is '/' and assign the result power * 27 for that case.

于 2012-04-03T21:28:12.077 回答