Làm cách nào để sắp xếp mảng các chuỗi chứa cả số âm và số dương trong c ++.?


8
String str[]={"-123","89","-10","456"};

strlà một mảng các chuỗi, với mỗi chuỗi có định dạng của một số nguyên và bạn phải thực hiện sắp xếp theo O(n log n)thời gian trên mảng này .

Các chuỗi trong strcó thể đại diện cho cả số nguyên dương và số âm. Độ dài tối đa của các chuỗi này là 1024 ký tự.

Tôi biết một giải pháp của vấn đề này là chuyển đổi các chuỗi thành số, sau đó so sánh chúng với nhau; Có giải pháp nào khác cho vấn đề này không?


1024 ký tự - tức là chữ số - bạn sẽ cần số nguyên rất lớn cho ...
Aconcagua

@RSahu lỗi của tôi, tôi đã chỉnh sửa câu hỏi ngay bây giờ
Emp1

@Aconcaguan vâng, tôi đã sử dụng thư viện tăng cường đa năng của cpp cho điều đó
Emp1

Một phiên bản khác của ý tưởng trong các câu trả lời thực hiện so sánh dựa trên chuỗi: bạn có thể phân vùng danh sách thành các phần âm và không âm, sau đó sử dụng hai hàm so sánh đơn giản hơn cho mỗi loại để sắp xếp các phần.
aschepler

Câu trả lời:


13

Một giải pháp khác là thực hiện chức năng so sánh của riêng bạn:

  • Kiểm tra ký tự đầu tiên của cả hai chuỗi. Nếu một bắt đầu bằng một chữ số và số còn lại bắt đầu bằng a -, thì chuỗi bắt đầu bằng - một số nhỏ hơn.
  • Nếu cả hai chuỗi bắt đầu bằng một chữ số, thì hãy so sánh độ dài của chuỗi. Chuỗi ngắn hơn là số nhỏ hơn. Nếu cả hai chuỗi có cùng độ dài, hãy thực hiện so sánh chuỗi tiêu chuẩn.
  • Nếu cả hai chuỗi bắt đầu với -, sau đó so sánh độ dài của chuỗi. Chuỗi dài hơn là số nhỏ hơn. Nếu cả hai chuỗi có cùng độ dài, hãy thực hiện so sánh chuỗi tiêu chuẩn, nhưng phủ nhận kết quả.

Nhưng chúng ta cần giả định rằng không có số 0 đứng đầu, chúng phải được bỏ qua khi xem xét độ dài chuỗi. Các số 0 âm ( "-0"), nếu chúng tồn tại, sẽ được sắp xếp trước các số bình thường, nhưng điều đó có vẻ tốt với tôi ...
Aconcagua

3
Điều đó có thể dễ dàng khắc phục. Sử dụng chỉ mục từ find_first_not_of("0")và chuyển những thứ đó sang compare()quá tải, yêu cầu pos / len cho cả hai mặt so sánh.
Tanveer Badar

@Aconcagua Bạn đúng là tôi đã không xem các số không hàng đầu. Cảm ơn @ TanveerBadar đã cung cấp giải pháp cho điều đó. Đối với các số 0 âm, việc sắp xếp chúng trước các số 0 dương có vẻ tốt đối với tôi.
dùng3386109

12

Đây là một ví dụ tối thiểu và có khả năng không đủ (không xử lý các số 0, khoảng trắng, v.v. hàng đầu, thực hiện những gì bạn muốn.

Các ý kiến ​​giải thích những gì nó đang làm. :)

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

int main() {
  std::vector<std::string> strings = {
      "-1", "-1", "-20", "-4", "3", "0", "-0", "1", "20", "20", "44020",
  };

  // Assumes everything in "strings" has no whitespace in it.
  // Assumes everything in "strings" does not have leading zeroes.
  // Assumes everything in "strings" is an ascii representaion of an integer.
  // Assumes everything in "strings" is nonempty.
  std::sort(strings.begin(), strings.end(),
            [](const std::string &a, const std::string &b) {
              const bool a_is_negative = a[0] == '-';
              const bool b_is_negative = b[0] == '-';
              if (a_is_negative != b_is_negative) {
                // If they have different signs, then whichever is negative is
                // smaller.
                return a_is_negative;
              } else if (a.length() != b.length()) {
                // If they have the same sign, then whichever has more
                // characters is larger in magnitude. When the sign is negative,
                // the longer (more digits) number is "more negative". When
                // positive, the longer (more digits) number is "more positive".
                return (a.length() < b.length()) != a_is_negative;
              } else {
                // Otherwise a lexicographic comparison of "a" and "b" will
                // determine which string is larger in magnitude. Using the same
                // logic above, we account for the "negative vs. positive"
                // comparison.
                return (a < b) != a_is_negative;
              }
            });

  for (const auto &str : strings) {
    std::cout << str << " ";
  }
  std::cout << std::endl;
}

Ah có vẻ như câu trả lời khác phác thảo logic tương tự như tôi đã viết trong phản hồi của mình. Tôi sẽ để nó lên mặc dù họ là người đầu tiên. Tôi dùng mã để diễn tả phản ứng của mình, anh dùng từ. :)
cực kỳ hấp dẫn vào

Chuyển đổi rõ ràng sang bool là không cần thiết, nếu bạn cung cấp kiểu trả về (trailing). Cá nhân tôi sẽ xem xét rằng dễ đọc hơn. Bạn cũng có thể sử dụng !=thay vì ^, có cùng kết quả cho booleans, nhưng kết quả là boolean đã có, một lần nữa làm cho diễn viên rõ ràng trở nên lỗi thời (và thêm vào đó là dấu ngoặc đơn ...).
Aconcagua

1
Chết tiệt, bạn đã đánh cắp câu trả lời (cơ hội) của tôi : Bản demo của tôi về coliru . ;-)
Scheff

Nice @Aconcagua - Tôi đã lười biếng và viết những suy nghĩ của mình thay vì nghĩ về việc viết mã sạch. Tôi đã chấp nhận đề xuất của bạn vì nó không thay đổi đáng kể câu trả lời.
druckermanly

Trong khi lambda có thể ổn, tôi nghĩ rằng lambda lớn và nó có ý nghĩa để có chức năng chuyên dụng thay thế ( less_as_number?).
Jarod42
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.