---
# System prepended metadata

title: “Memento” 设计模式是一种行为型设计模式，用于捕获一

---

這是原題 幫我找
Solutions
Solution 1: Simulation

We can simulate the process according to the problem's requirements. Note that if it is the last line, or if there is only one word in the line, then we should align to the left. Otherwise, we should distribute the spaces evenly.

The time complexity is 
, and the space complexity is 
. Here, 
 is the sum of the lengths of all words.

先拿第一个字 然后开始 while loop check if count+ word[i]+1 会不会 <= maxWidth
**不要 { }!!!**
吧这行的字都 push_back 到temp vector 里

special case: 假如是最后一行 或者这行只有一个字 要在右边加满空格
**加上word[i].size()!!**
class Solution {
public:
    vector<string> fullJustify(vector<string>& words, int maxWidth) {
        vector<string> ans;
    
        //不能 i++
        //不是word[i] 是 word
        换成while（）？
    
        for (int i = 0, n = words.size(); i < n;) {
            vector<string> t = {words[i]};
            int cnt = words[i].size();
            ++i;
            while (i < n && cnt + 1 + words[i].size() <= maxWidth) {
                cnt += 1 + words[i].size();
                t.emplace_back(words[i++]);
            }
            //special case: 假如是最后一行 或者这行只有一个字 要在右边加满空格
            if (i == n || t.size() == 1) {
                string left = t[0];
                for (int j = 1; j < t.size(); ++j) {
                    left += " " + t[j];
                }
                string right = string(maxWidth - left.size(), ' ');
                ans.emplace_back(left + right);
                continue;
            }
            //我每个词都加一个空格 所以现在要剪掉空格 但第一个字没有空格 所以要-1                       
            int spaceWidth = maxWidth - (cnt - t.size() + 1);
            //每个空格的长度要相等                               
            int w = spaceWidth / (t.size() - 1);
            //假如还有多的 要evenly distribute
            int m = spaceWidth % (t.size() - 1);
            string row;
            //我们现在来建这个 row **每个词先加w的空格**
            //假如有多出来了的空格（m）要加上去
            //假如 m 是 4 那就前四个词要多加一个空格
            //所以我们判断 m < j 的话就加一个空格
            for (int j = 0; j < t.size() - 1; ++j) {
                row += t[j] + string(w + (j < m ? 1 : 0), ' ');
            }
            row += t.back();
            ans.emplace_back(row);
        }
        return ans;
    }
};

The "right-hand" or right-hand side (RHS) of an expression in programming languages like C++ possesses several properties and characteristics:

Value: The right-hand side represents a value or an expression that is evaluated to produce a value.

Operand: It serves as an operand for various operators such as assignment (=), arithmetic (+, -, *, /), comparison (==, >, <), and logical (&&, ||) operators.

Evaluation: The right-hand side is evaluated before any operation that uses it. For example, in an assignment statement, the RHS is evaluated first, and then the resulting value is assigned to the left-hand side (LHS) variable.

Variables and Constants: The RHS can consist of variables, constants, literals, function calls, or more complex expressions, depending on the context.

Immutability: In some cases, the RHS can represent a value that is immutable, meaning it cannot be changed. For example, a constant value like const int x = 5; has an RHS of 5, which cannot be modified.

Side Effects: In some situations, evaluating the RHS may have side effects, such as modifying the state of an object or invoking a function with side effects.

Data Types: The data type of the RHS must be compatible with the operation or assignment it participates in. Type mismatches can lead to compilation errors or unexpected behavior.

Complexity: The RHS can be a simple value or a complex expression involving multiple operations and sub-expressions.

Order of Evaluation: The order in which sub-expressions within the RHS are evaluated follows the rules of the language and operator precedence. Some languages specify left-to-right or right-to-left evaluation, while others allow compiler optimization to determine the order.

Errors: Incorrect or incompatible RHS expressions can lead to runtime errors or logical errors in the program.

In summary, the "right-hand" or RHS of an expression is a critical component in programming, representing values and expressions that are used in various operations. Understanding its properties and characteristics is important for writing correct and efficient code.


左和右（LHS 和 RHS）：

左邊（LHS）：通常指的是賦值操作（=）的左側，代表了值被賦予的目標。例如，在語句 int x = 5; 中，"x" 是賦值操作的左邊，表示值 5 將被賦予 "x"。

右邊（RHS）：指的是賦值操作（=）的右側，代表了值或表達式將被賦予左側。在語句 int x = 5; 中，"5" 是賦值操作的右邊，表示被賦予 "x" 的值是 5。

總結來說，LHS 代表賦值的目標，而 RHS 代表賦值的源頭或值。

const：

const：在 C++ 中是一個關鍵字，用於表示變數的值在初始化後不能被修改。它可以應用於變數、指針和成員函數。

對於變數：const int x = 5; 声明一個常數整數變數 "x"，其值不能被修改。
對於指針：const int* ptr = &x; 声明一個指向常數整數的指針 "ptr"，意味著你不能修改 "ptr" 指向的值。
對於成員函數：void foo() const; 声明一個常數成員函數，確保該函數不修改對象的數據成員。
"const" 用於創建不可變的值，並確保變數或實體在初始化後不會更改其值。

總結來說，"左" 和 "右" 指的是賦值操作的兩側，"左" 是目標，"右" 是源頭。"const" 是 C++ 中用於聲明常數和強制不可變性的關鍵字，可應用於變數、指針和成員函數，這些概念雖然不同，但都與變數和表達式在語言中的使用和操作有關。





智能指针（Smart Pointer）是C++中的一个概念，用于管理动态分配的内存，以减少内存泄漏和资源管理问题。智能指针是C++标准库提供的一组类，通常用于替代裸指针（raw pointers），以提供更安全、更方便的内存管理。

主要的智能指针类型包括以下三种：

std::shared_ptr：共享指针

std::shared_ptr 允许多个指针共享对同一块内存的所有权。当最后一个 std::shared_ptr 被销毁时，它会自动释放所管理的内存。这种智能指针用于构建多个拥有者的资源共享模型，比如多个对象需要访问同一块内存。
std::unique_ptr：独占指针

std::unique_ptr 表示对内存的唯一所有权，不能被多个指针共享。当 std::unique_ptr 被销毁时，它会自动释放所管理的内存。这种智能指针用于确保只有一个拥有者的资源管理模型，以避免悬空指针和内存泄漏。
std::weak_ptr：弱引用指针

std::weak_ptr 是与 std::shared_ptr 一起使用的，用于解决循环引用问题。std::weak_ptr 允许观察 std::shared_ptr 拥有的资源，但不会增加引用计数。如果最后一个 std::shared_ptr 被销毁，即使有 std::weak_ptr 指向资源，也能正常释放资源。
智能指针的主要优势包括：

自动内存管理：当智能指针超出范围时，它们会自动释放所管理的内存，从而避免内存泄漏。

安全性：智能指针提供了更高级别的内存管理，减少了悬空指针和野指针的问题。

方便性：使用智能指针通常更加方便，不需要手动管理资源的分配和释放。

避免资源泄漏：智能指针通过引用计数等机制来跟踪资源的所有权，确保资源在不再需要时被正确释放。

总之，智能指针是C++中的一种强大工具，用于改进内存管理和资源管理。它们提供了更安全、更方便的方法来处理动态分配的内存，有助于减少许多与裸指针相关的常见错误。






move semantics

std::unique_ptr 通过移动语义（move semantics）来传递所有权。在C++中，移动语义是一种机制，允许将资源（如内存）的所有权从一个对象转移到另一个对象，而不是复制资源，从而提高了性能和资源管理效率。

以下是使用 std::unique_ptr 传递所有权的一般步骤：

创建 unique_ptr 对象：首先，创建一个 std::unique_ptr 对象，它拥有某个资源（通常是内存）的所有权。例如：

cpp
Copy code
std::unique_ptr<int> ptr = std::make_unique<int>(42);
这里，ptr 拥有一个整数类型的内存块的所有权，其值为 42。

传递所有权：要将 std::unique_ptr 的所有权传递给另一个对象，您可以使用移动语义。通过将右值引用传递给接受 std::unique_ptr 的函数或构造函数，资源的所有权会从一个对象转移到另一个对象。例如：

cpp
Copy code
std::unique_ptr<int> anotherPtr = std::move(ptr); // 所有权从 ptr 转移到 anotherPtr
在这个示例中，std::move 将 ptr 转换为右值引用，然后将其赋值给 anotherPtr，这将导致 ptr 失去对资源的所有权，而 anotherPtr 获得了该资源的所有权。

资源的释放：在 std::unique_ptr 被销毁时（例如，超出作用域），它会自动释放它所拥有的资源。这确保了资源的正确释放，避免了内存泄漏。

使用 std::unique_ptr 传递所有权的关键是要理解移动语义以及如何使用 std::move 来将资源的所有权从一个对象转移到另一个对象。这种方式有助于确保资源在不再需要时被正确释放，同时提高了性能。



移动语义在C++中有多个用途，除了在 std::unique_ptr 中用于传递所有权之外，还可以在以下情境中使用移动语义：

移动构造函数和移动赋值操作符：

自定义类可以通过实现移动构造函数（Move Constructor）和移动赋值操作符（Move Assignment Operator）来启用移动语义。这允许对象的资源（如动态分配的内存或其他资源）在传递、返回或赋值时以高效的方式转移所有权。
STL容器和算法：

标准模板库（STL）中的容器类（如 std::vector、std::string、std::deque 等）已经支持了移动语义。在将容器元素插入或从容器中移除时，移动语义可以提高性能，因为它允许元素的内容以高效方式从一个位置移动到另一个位置，而不是进行深拷贝。
返回临时对象：

在函数中，您可以创建并返回一个临时对象，通过使用移动语义来提高效率。这通常用于返回临时的大型数据结构，如字符串或容器。
传递和处理大型数据结构：

当传递或处理大型数据结构时，移动语义可以避免不必要的数据复制。通过将数据的所有权从一个对象传递到另一个对象，可以提高性能和效率。
资源管理：

在资源管理方面，如文件句柄、网络连接或数据库连接等，移动语义可以用于管理资源的所有权和生命周期，确保在资源不再需要时正确释放它们。
自定义智能指针：

如果您编写自己的智能指针类（例如，不是使用 std::unique_ptr），则可以使用移动语义来实现资源的高效转移和管理。
性能优化：

在一般情况下，通过移动而不是复制数据可以提高性能，特别是对于大型数据结构或需要频繁传递的对象。
总之，移动语义是C++中的一项重要功能，用于提高性能和资源管理效率。它可以用于自定义类、STL容器、函数返回值、资源管理和其他各种情况，以减少不必要的数据复制并更高效地管理资源。

進程間通信（IPC）指的是允許在計算機上運行的不同進程之間進行通信和共享數據的機制和技術。在各種操作系統中，有幾種實現IPC的方法，具體的方法取決於應用程序的特定要求。以下是一些常見的IPC方法：

管道（Pipes）：管道是一種簡單的IPC形式，用於在兩個相關進程之間進行通信，其中一個進程的輸出用作另一個進程的輸入。有兩種類型的管道：無名管道（使用pipe()系統調用創建）和有名管道（也稱為FIFO）。

消息隊列（Message Queues）：消息隊列提供了一種機制，使一個進程能夠向另一個進程發送結構化消息。進程可以讀取和寫入消息隊列，消息通常按照先進先出（FIFO）的順序檢索。

共享內存（Shared Memory）：共享內存允許多個進程訪問同一塊內存區域，使它們能夠直接共享數據。這是最快速的IPC機制之一，但需要謹慎同步以避免數據損壞。

套接字（Sockets）：套接字通常用於在網絡上進行進程間通信，但也可以用於同一台計算機上的IPC。它們提供了一種多功能的方式，使進程能夠使用不同的協議（如TCP/IP或Unix域套接字）進行通信。

信號（Signals）：信號是一種異步IPC形式，其中一個進程可以向另一個進程發送信號，通知它某個事件或請求某個操作。常見的信號包括SIGTERM、SIGINT和SIGKILL。

信號量（Semaphores）：信號量是用於控制多個進程之間共享資源訪問的同步原語。它們可用於實現鎖、互斥體和其他同步機制。

基於文件的IPC：進程可以使用文件或特殊的類文件對象進行IPC。這可以包括內存映射文件、有名管道（FIFO）或常規文件作為通信的形式。

遠程過程調用（RPC）：RPC允許進程像本地函數調用一樣調用其他進程中的函數或過程。像D-Bus和gRPC這樣的技術提供了RPC的IPC機制。

分佈式對象模型：在分佈式系統中，面向對象的IPC機制允許不同進程中的對象進行通信並調用彼此的方法。CORBA和DCOM是分佈式對象模型的示例。

內存映射文件（Memory-mapped Files）：進程可以將文件直接映射到其地址空間中，從而使它們能夠通過讀寫相同的內存映射區域來共享數據。

消息傳遞（Message Passing）：在某些操作系統中，支持消息傳遞系統，進程可以通過發送和接收消息來進行通信，類似於電子郵件。

選擇IPC方法取決於性能要求、實現的容易程度、平台兼容性和安全考慮等因素。不同的情況可能需要不同的IPC機制，有時可以在同一應用程序中使用多種方法。




























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

using namespace std;

// # 1. Given an array of words and a width maxWidth, format the text such that each line has exactly maxWidth characters and is fully (left and right) justified.
// # 2. Pack as many words as you can in each line. Pad extra spaces ' ' when necessary.
// # 3. Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.
// # 4. For the last line of text, it should be left justified and no extra space is inserted between words.

// # Input: words = ["This", "is", "an", "example", "of", "text", "justification."], maxWidth = 16
// # Output:
// # [
// #    "This    is    an",
// #    "example  of text",
// #    "justification.  "
// # ]

// # Input: words = ["What","must","be","acknowledgment","shall","be"], maxWidth = 16
// # Output:
// # [
// #   "What   must   be",
// #   "acknowledgment  ",
// #   "shall be        "
// # ]

// # Input: words = ["Science","is","what","we","understand","well","enough","to","explain","to","a","computer.","Art","is","everything","else","we","do"], maxWidth = 20
// # Output:
// # [
// #   "Science  is  what we",
// #   "understand      well",
// #   "enough to explain to",
// #   "a  computer.  Art is",
// #   "everything  else  we",
// #   "do                  "
// # ]


vector<string> func1(vector<string>& words, int maxWidth){
    vector<string> ans;
    int m = words.size();
    for(int i = 0 ; i < m ; ){
        vector<string> t = {words[i]};
        int cnt = words[i].size();
        i++;
        while(i < m && cnt + 1 + words[i].size() <= maxWidth){
            cnt += 1 + words[i].size();
            t.push_back(words[i]);
            i++;
        }
        if(i == m || t.size() == 1){
            string left = t[0];
            for(int j = 1 ; j < t.size() ; j++){
                left += " " + t[j];
            }
            string right = string(maxWidth - left.size(), ' ');
            ans.push_back(left + right);
            continue;
        }
        int spaceWidth = maxWidth - (cnt - t.size() + 1);
        int w = spaceWidth / (t.size() - 1);
        int m = spaceWidth % (t.size() - 1);
        
        string strPush;
        for(int j = 0 ; j < t.size() - 1; j++){
            strPush += t[j];
            if(j < m){
                strPush += string(w + 1, ' ');
            }
            else
                strPush += string(w, ' ');
        }
        strPush += t.back();
        ans.push_back(strPush);
    }
    
    return ans;
}
vector<int> vec = {1, 2, 3};
vector<int> vec2 = move(vec);
int i = 10;
int main() {
    // # Input: words = ["This", "is", "an", "example", "of", "text", "justification."], maxWidth = 16
    vector<string> test1 = {"This", "is", "an", "example", "of", "text", "justification."};
    vector<string> test2 = {"What","must","be","acknowledgment","shall","be"};
    vector<string> test3 = {"Science","is","what","we","understand","well","enough","to","explain","to","a","computer.","Art","is","everything","else","we","do"};
    int maxWidth = 20;
    vector<string> ret2 = func1(test3, maxWidth);
    for(auto str : ret2){
        cout << str << endl;
    }
    return 0;
}
