安装

在vue ui中的插件处安装

使用

store 文件夹下面的 index.js

import { createStore } from 'vuex'

export default createStore({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

state 存放的是变量, getters 存放的是需要由 state 中的变量动态计算生成的变量, mutations 存放的是直接对 state 中变量进行修改的函数, actions 存放的是对 state 的各种更新方式(不能对state进行直接修改), modules 可以将 state 进行分割,避免代码过长。

在标签中使用变量
示例:

<ul class="navbar-nav" v-if="!$store.state.user.is_login">
    <li class="nav-item">
    <router-link class="nav-link" :to="{name: 'login', params: {}}">登录</router-link>
    </li>
    <li class="nav-item">
    <router-link class="nav-link" :to="{name: 'register', params: {}}">注册</router-link>
    </li>
</ul>
<ul class="navbar-nav" v-else>
    <li class="nav-item">{{ $store.state.user.username }}</li>
</ul>

使用 $store 访问store,user是一个module,所以通过这样的方式来访问user中的is_login变量

script 中使用
示例:

import { useStore } from 'vuex';
export default {
  name: 'UserListView',
  components: {
  },
  setup() {
    const store = useStore();
    console.log(store.state.user.username);
  }
}

在外部使用 actions 中的函数需要用到 useStore 这个组件
例如:

setup() {
    const store = useStore();
    const login = () => {
      store.dispatch("login", {
        username: username.value,
        password: password.value,
        succuss() {
          console.log("success");
        },
        error() {
          console.log("error");
        }
      })
    }
    return {
      login
    }
}

这里用 store 来接收 useStore() 返回的对象,使用 store.dispatch 来调用 login 函数, store.dispatch 传了两个参数,第一个是函数名,第二个是数据。

user.js:

import $ from 'jquery';
const ModuleUser = {
    state: {
        id: "",
        username: "",
        photo: "",
        followerCount: 0,
    },
    getters: {
    },
    mutations: {
    },
    actions: {
        login(context, data) {
            console.log(data);
            $.ajax({
                url: "xxx",
                type: "POST",
                data: {
                    username: data.username,
                    password: data.password,
                },
                success(resp) {
                    console.log(resp)
                }
            })
        }
    },
    modules: {

    }
};
export default ModuleUser;

actions中的login函数两个参数,第一个是上下文context,里面有很多自带的api,第二个是数据,可以通过外部使用这个函数时传入。

index.js:

import { createStore } from 'vuex'
import ModuleUser from './user'
export default createStore({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
    user: ModuleUser,
  }
})

这里user单独写一个module独立出去,只要在index.js中引入并在modules中添加这个变量即可。

mutations 中的函数需要传两个参数一个是 state 用来访问state中的变量,另外一个是自定义的参数。

mutations: {
    updateUser(state, user) {
        state.id = user.id;
        state.username = user.username;
        state.photot = user.photo;
        state.followerCount = user.followerCount;
        state.access = user.access;
        state.refresh = user.refresh;
        state.is_login = user.is_login;
    },
},

actions 中使用 mutations 中的函数示例:

context.commit("updateUser", {
    ...resp,
    access: access,
    refresh: refresh,
    is_login: true,
})

使用 context 中的commit函数,传两个参数,一个是函数名称,另外一个是自定义参数。

问题描述

小S正在帮助她的朋友们建立一个搜索引擎。为了让用户能够更快地找到他们感兴趣的帖子,小S决定使用倒排索引。倒排索引的工作原理是:每个单词都会关联一个帖子ID的列表,这些帖子包含该单词,且ID按从小到大的顺序排列。
例如,单词“夏天”可能出现在帖子1、帖子3和帖子7中,那么这个单词的倒排链就是 [1, 3, 7]。如果用户想同时找到包含“夏天”和“海滩”的帖子,小S需要找出两个倒排链的交集,且将结果按照从大到小的顺序输出。现在,给定两个单词的倒排链数组 a 和 b,请你帮助小S找出同时包含这两个单词的帖子ID,并按从大到小的顺序返回结果。


测试样例

样例1:

输入:a = [1, 2, 3, 7], b = [2, 5, 7]
输出:[7, 2]

样例2:

输入:a = [1, 4, 8, 10], b = [2, 4, 8, 10]
输出:[10, 8, 4]

样例3:

输入:a = [3, 5, 9], b = [1, 4, 6]
输出:[]

样例4:

输入:a = [1, 2, 3], b = [1, 2, 3]
输出:[3, 2, 1]

思路:
通过迭代器逐个比较a和b两个vector中的值,当发现一样就放到答案C中,如果a的值大于b的值就让b的迭代器++,反之如果a的值小于b的值就让a的迭代器++,当有一个vector被遍历完时while循环结束,使用reverse函数反转vector然后返回。

代码:

vector<int> solution(vector<int>& a, vector<int>& b) {
    vector<int> C;
    auto A = a.begin(), B = b.begin();
    while(A != a.end() && B != b.end())
    {
        if(*A == *B) C.push_back(*A), ++A, ++B;
        else if (*A > *B) ++B;
        else ++ A;
    }
    reverse(C.begin(), C.end());
    return C;
}

ps:我发现稀土掘金的简单题都好有意思,可以学到挺多stl容器的用法。

url: https://www.luogu.com.cn/problem/P2280

tag:
前缀和

思路:
这是一道二维前缀和。根据题意可以知道边长为m的爆破正方形最多可以破坏 m m 个目标,所以题目就变成了找到地图范围内,大小为m m的子矩阵中总价值最大的值。地图的范围可以直接定义成边界5000 5000,也可以像代码中的一样,一开始为m m表示至少要有一个子矩阵,之后每次读入一个新的目标时通过目标的坐标来更新地图大小。遍历每一个子矩阵可以通过从x = m和y = m开始遍历每一个点作为子矩阵的右下端点然后通过计算得到左上端点然后再通过二维前缀和的公式计算求最大值即可。

代码:

#include <iostream>
#include <cstring>
using namespace std;
const int N = 5010;
int p[N][N];
int n, m;
int nx, my;
int main()
{
    scanf("%d%d", &n, &m);
    nx = my = m;
    // 读数
    for (int i = 0; i < n; i ++)
    {
        int x, y, w;
        scanf("%d%d%d", &x, &y, &w);
        x ++, y ++;
        nx = max(x, nx), my = max(y, my);
        p[x][y] += w;
    }
    // 计算前缀和
    for (int i = 1; i <= nx; i ++)
        for (int j = 1; j <= my;  j++)
        {
            p[i][j] += p[i - 1][j] + p[i][j - 1] - p[i -1][j - 1];
        }
    // 求子矩阵中总价值最大的值
    int res =  -1;
    for (int i = m; i <= nx; i ++)
        for (int j = m; j <= my; j ++)
        {
            res = max(res, p[i][j] - p[i - m][j] - p[i][j - m] + p[i - m][j - m]);
        }
    cout << res <<endl;
    return 0;
}

url: https://www.luogu.com.cn/problem/B3738

tag:
模拟,数学

思路:
数据范围比较小,可以用模拟的方式来通过这道题。比较难的部分应该是蛇形填充。这里可以先用一个数组来存放四个前进的方向。之后每次都判断一下前进之后的位置符不符合要求(不越界且当前位置没有被填充过),如果符合要求则前进,然后将数字放进矩阵,否则就换一个方向。

代码:

#include <iostream>
using namespace std;
int n, x, y;
const int N = 22;
int p[410], dp[N][N], d;
int dir[4][2] = {
        {0, 1},
        {1, 0},
        {0, -1},
        {-1, 0},
};
bool is_pr(int x)
{
    for (int i = 2; i * i <= x; i ++)
    {
        if (x % i == 0) return false;
    }
    return true;
}
int main()
{
    cin >> n >> x >> y;
    int k = 2;
    for (int i = 1; i <= n * n; i ++)
    {
        while (!is_pr(k++));
        p[i] = --k;
        k ++;
    }
    int nx = 0, ny = 0;
    dp[0][0] = p[1];
    for (int i = 2; i <= n * n; i ++)
    {
        int tmpx, tmpy;
        tmpx = nx + dir[d][0], tmpy = ny + dir[d][1];
        if (tmpx >= n || tmpx < 0 || tmpy >= n || tmpy < 0 || dp[tmpx][tmpy])
        {
            d = (d + 1) % 4;
            tmpx = nx + dir[d][0], tmpy = ny + dir[d][1];
        }
        nx = tmpx, ny = tmpy;
        dp[nx][ny] = p[i];
    }
    cout << dp[x - 1][y  - 1] << endl;
    return 0;
}

问题描述
小M想要通过查看往届游戏比赛的排名来确定自己比赛的目标分数。他希望找到往届比赛中排名第三的分数,作为自己的目标。具体规则如下:

如果分数中有三个或以上不同的分数,返回其中第三大的分数。
如果不同的分数只有两个或更少,那么小M将选择最大的分数作为他的目标。
请你帮小M根据给定的分数数组计算目标分数。

测试样例
样例1:

输入:n = 3,nums = [3, 2, 1]
输出:1

样例2:

输入:n = 2,nums = [1, 2]
输出:2

样例3:

输入:n = 4,nums = [2, 2, 3, 1]
输出:1

题解:

int solution(int n, std::vector<int> nums) {
    set<int> uniqueNums(nums.begin(), nums.end());
    if (uniqueNums.size() < 3) return *uniqueNums.rbegin();
    auto it = uniqueNums.rbegin();
    it ++;
    it ++;
    return *it;
}

这里主要用到了set的去重和排序。set是从小到大排,所以为了拿到最大值用来 rbegin() 这个反向迭代器。因为std::set 的迭代器是双向迭代器所以没有 += -= 这种操作。

双向迭代器:只支持单步的前进和后退操作,即使用 ++it--it。它们不支持像 +=-= 这样的算术操作。

还有一个用法很有意思就是 set<int> uniqueNums(nums.begin(), nums.end()); 可以通过给set传一个范围(vector)来创建set。同样的用法在vector也有,例如:

std::vector<int> vec(uniqueNums.begin(), uniqueNums.end());
// 现在可以使用随机访问操作
return vec[vec.size() - 3];